N
nob@lit-forge
Bash / Zsh ワンライナー集
ログから特定時刻を抜き出す、CSV を整形する、複数ファイルを一括リネーム、ファイル差分集計など、日常で 1 行書けば済む Bash / Zsh のワンライナーを実例中心にまとめた早見表。パイプ・xargs・プロセス置換を組み合わせた実戦パターン。
#Bash#Zsh#ワンライナー#shell
ログから情報を抜く
# 直近 1 時間の ERROR 行を色付きでタイムスタンプ順に
grep -a "ERROR" app.log | grep "$(date -u +"%Y-%m-%dT%H" -d '1 hour ago')"
# ログ行を 5xx ステータスでフィルタ、リクエストパスの頻度を集計
awk '$9 ~ /^5/ {print $7}' access.log | sort | uniq -c | sort -rn | head
# nginx ログから User-Agent 上位 10
awk -F\" '{print $6}' access.log | sort | uniq -c | sort -rn | head -10
# 日付範囲で絞る(grep の範囲検索)
awk '/2026-04-18T10:00/,/2026-04-18T11:00/' app.logファイル一括操作
# 拡張子を一括変換(jpeg → jpg)
for f in *.jpeg; do mv "$f" "${f%.jpeg}.jpg"; done
# ファイル名に日付 prefix を付ける
for f in *.txt; do mv "$f" "$(date +%Y%m%d)-$f"; done
# 同じディレクトリで .bak バックアップを作成
for f in *.conf; do cp "$f" "$f.bak"; done
# 1MB 未満の画像を一括で最適化(ImageMagick)
find . -name "*.png" -size -1M -exec convert {} -strip -quality 85 {} \;
# 空のディレクトリを削除
find . -type d -empty -delete
# 最終更新が 30 日以上前のファイルを削除
find /tmp -type f -mtime +30 -deleteCSV / TSV / JSON 整形
# CSV の N 列目を抜く(カンマ区切り)
awk -F, '{print $3}' data.csv
# CSV にヘッダ付きで新しい列を追加(row 番号)
awk 'BEGIN{FS=OFS=","} NR==1{print "no", $0; next} {print NR-1, $0}' data.csv
# TSV を JSON 配列に変換(jq 使用)
jq -Rsn '[inputs | split("\n") | .[] | select(length>0) | split("\t")]' < data.tsv
# JSON から特定キーの値だけ抽出
jq '.users[] | select(.active==true) | .email' users.json
# 大きな JSON を整形
jq '.' < big.json | less
# CSV ヘッダを維持して重複行を削除
awk 'NR==1 || !seen[$0]++' data.csvプロジェクト横断検索
# 大きいファイル上位 10 件 du -ah . | sort -rh | head -10 # node_modules 除外で TODO コメントを探す grep -rn --exclude-dir=node_modules --include="*.ts" "TODO" . # ripgrep でより高速に(.gitignore 尊重) rg -n "TODO" --type ts # 特定文字列を含むファイルの一覧だけ出す grep -rl "deprecated" src/ # コミット済みの全ファイルから検索(git grep) git grep -n "apiKey"
ネットワーク調査
# HTTP レスポンス時間の内訳(DNS / 接続 / TTFB / 総計)
curl -w '@-' -o /dev/null -s https://example.com <<'EOF'
namelookup: %{time_namelookup}\n
connect: %{time_connect}\n
starttransfer: %{time_starttransfer}\n
total: %{time_total}\n
EOF
# あるホストの Let's Encrypt 証明書の残日数
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -enddate
# 開いてる port を一発で列挙
ss -tlnp | awk 'NR>1 {print $4}' | sort -u
# IPv4 アドレスだけ抽出
ip -4 a | awk '/inet / {print $2}'Git ワンライナー
# 直近のブランチを最近使った順に git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short)' | head # マージ済ブランチを一括削除 git branch --merged main | grep -v 'main\|\*' | xargs -n1 git branch -d # 行数の変更が多いファイル TOP 10 git log --format='' --name-only | sort | uniq -c | sort -rn | head # 特定ファイルをいじった全コミット git log --follow --oneline -- path/to/file # 自分のコミット数 git log --author="$(git config user.email)" --oneline | wc -l
日時・データ生成
# ISO 8601(UTC) date -u +"%Y-%m-%dT%H:%M:%SZ" # N 分前の時刻 date -d '15 minutes ago' +"%Y-%m-%d %H:%M" # タイムスタンプ(秒)を ISO 8601 に date -d @1735689600 -u +"%Y-%m-%dT%H:%M:%SZ" # ランダム英数字 16 文字 head -c 32 /dev/urandom | base64 | tr -dc 'A-Za-z0-9' | head -c 16 # UUID v4 を生成 cat /proc/sys/kernel/random/uuid # 1〜100 のランダム整数 shuf -i 1-100 -n 1
応用: データパイプラインの定型
# アクセスログ → 1 分ごとの RPS を集計 → CSV
awk '{print $4}' access.log | awk -F: '{print $2":"$3}' | sort | uniq -c | awk 'BEGIN{OFS=","}{print $2, $1}'
# ファイル名の衝突チェック(大文字小文字違いの重複検出)
find . -type f | awk '{lower=tolower($0); count[lower]++; paths[lower]=paths[lower] "\n" $0} END {for (k in count) if (count[k]>1) print paths[k]}'
# tar で転送中の進捗を見る
tar -cf - src/ | pv | ssh host 'cat > dst.tar'
# xargs の並列実行(-P 4 で 4 並列)
find . -name "*.png" -print0 | xargs -0 -n1 -P4 pngquant --quality=65-80 --skip-if-largerTips
- 危険な操作は
echoで dry-run:for f in *.tmp; do echo rm "$f"; doneで意図を確認してから実行 - 引数に空白・記号が混ざるなら必ず
" "で囲む: 変数展開は原則クオート - xargs には
-0(NUL 区切り):find -print0 | xargs -0で空白 / 改行入りファイル名にも耐える - 長いワンライナーは関数化:
~/.bashrcにfunction rg-todo() { rg -n "TODO" "$@"; }を追加すると習慣化しやすい