Linux コマンド中級編 — find / grep・awk・sed / ジョブ管理
対象読者: ls cd cat などの基本コマンドは使えるが、もう一段階上のCLI操作を身につけたい方
動作確認環境: Ubuntu 22.04 / bash 5.1
はじめに
Linuxのコマンドラインをなんとなく使えるようになったけど、こんな経験はないでしょうか?
-
findでファイルを探そうとして毎回オプションを調べ直している -
grepは使えるがawkとsedの使い分けがよくわからない - バックグラウンド実行を
&で雑にやっているが、プロセスの扱いがよくわかっていない
この記事ではその3つをまとめて整理します。
1. find — ファイル検索を本当に使いこなす
基本構文
find <検索パス> <条件> [<アクション>]
アクションを省略すると -print(マッチしたパスを表示)が使われます。
よく使う条件オプション
# 名前で検索(ワイルドカード使用時はクォートが必要)
find . -name "*.log"
# 大文字小文字を無視
find . -iname "readme*"
# ファイルタイプで絞り込み(f=ファイル, d=ディレクトリ, l=シンボリックリンク)
find /etc -type f -name "*.conf"
# 更新日時で絞り込み(n日以内に変更されたファイル)
find . -mtime -3
# ファイルサイズで絞り込み(100MB以上)
find /var -size +100M
# 権限で絞り込み
find /usr/bin -perm 755
※ワイルドカードとは
➡「**ファイル名」やパターンマッチングで使う「任意の文字列を表す特殊文字」**のこと
複数条件の組み合わせ
# AND(デフォルト)
find . -name "*.sh" -type f
# OR
find . -name "*.jpg" -o -name "*.png"
# NOT
find . -not -name "*.log"
-exec でアクションを実行する
findの特徴として検索結果に対してそのままコマンドを実行できる点です。
※検索結果を確認せずに処理を実行することは、業務上危険なので検索結果を確認してから実行する事を推奨します。
# 見つかったファイルを削除
find . -name "*.tmp" -exec rm {} \;
# 見つかったファイルのパーミッションを変更
find . -name "*.sh" -exec chmod 755 {} \;
xargs との使い分け
# -exec と xargs はほぼ同じことができる
find . -name "*.log" | xargs gzip
# ファイル名にスペースが含まれる場合は -print0 と xargs -0 を組み合わせる
find . -name "* *" -print0 | xargs -0 rm
使い分けの目安
- シンプルなケースは
-exec ... +が手軽 - パイプで別コマンドに渡す場合は
xargs - ファイル名にスペースが含まれるなら
-print0 | xargs -0
2. grep / awk / sed:違いと使いどころをまとめて解説
この3つは「何をしたいか」で使い分けます。
| コマンド | 概要 |
|---|---|
grep |
行単位でパターンにマッチした行を抽出するコマンド |
awk |
フィールド単位でデータを抽出・集計・加工するコマンド* |
sed |
文字列を置換・削除するコマンド |
grep — 行の絞り込み
# 基本
grep "error" /var/log/syslog
# 大文字小文字を無視
grep -i "warning" app.log
# マッチしない行を表示(逆マッチ)
grep -v "DEBUG" app.log
# OR条件("error、warn、fatalのいずれかを含む)
grep -E "error|warn|fatal" app.log
# 再帰的に検索(ディレクトリ以下すべて)
grep -r "TODO" ./src/
# マッチした行数だけ表示
grep -c "404" access.log
# ファイル名だけ表示(-r で再帰検索と組み合わせて使う)
grep -rl "password" /etc/
awk — 列の操作と集計
awk はスペース区切りの各フィールドを $1, $2 ... で参照できます($0 は行全体)。
# 第1列と第3列だけ表示
awk '{print $1, $3}' access.log
# 区切り文字を指定(CSVなど)
awk -F ',' '{print $2}' data.csv
# 条件付きフィルタ(第9列が404の行だけ)
awk '$9 == 404 {print $0}' access.log
# 合計を計算(第5列の合計)
awk '{sum += $5} END {print sum}' access.log
# 行数をカウント(grep -c と同等)
awk 'END {print NR}' access.log
# 特定のパターンにマッチした行の列を加工
awk '/ERROR/ {print NR, $0}' app.log
sed — 文字列の置換・削除
# 基本的な置換(各行の最初のマッチのみ)
sed 's/foo/bar/' file.txt
# 全マッチを置換(g フラグ)
sed 's/foo/bar/g' file.txt
# ファイルを直接書き換える(-i オプション)
sed -i 's/old_domain/new_domain/g' config.txt
# 特定の行を削除(3行目を削除)
sed '3d' file.txt
# パターンにマッチした行を削除
sed '/^#/d' config.txt # コメント行を削除
# 特定の行範囲だけ処理(5〜10行目)
sed '5,10s/foo/bar/g' file.txt
# 行を追加(3行目の後に追加)
sed '3a\追加する行' file.txt
# -i.bak のようにバックアップ拡張子を指定するとより安全
# 元ファイルが config.txt.bak として保存される
sed -i.bak 's/old_domain/new_domain/g' config.txt
実践:パイプで組み合わせる
# Nginxのアクセスログから404エラーのIPアドレスを集計
grep "404" /var/log/nginx/access.log \
| awk '{print $1}' \
| sort | uniq -c | sort -rn \
| head -10
# 設定ファイルからコメントと空行を除いた内容だけ表示
grep -v "^#" /etc/ssh/sshd_config | sed '/^$/d'
# CSVから特定の列を抽出して処理
cat data.csv | awk -F ',' '$3 > 1000 {print $1, $3}'
覚え方のコツ
- 「この行が必要か不要か」→
grep - 「この列の値を取り出したい・計算したい」→
awk - 「この文字列をこの文字列に変えたい」→
sed
3. ジョブ管理 — バックグラウンド実行を正しく扱う
フォアグラウンドとバックグラウンド
ターミナルで実行するプロセスには2つのモードがあります。
- フォアグラウンド: 通常の実行。完了するまでターミナルが占有される
- バックグラウンド: ターミナルを占有せずに裏で動く
# バックグラウンドで実行(& をつける)
./long_process.sh &
# => [1] 12345 ← [ジョブ番号] PID
# 実行中のジョブ一覧を確認
jobs
# => [1]+ Running ./long_process.sh &
フォアグラウンド ↔ バックグラウンドの切り替え
# フォアグラウンドで実行中のプロセスを一時停止
Ctrl + Z
# => [1]+ Stopped ./long_process.sh
# バックグラウンドで再開(bg = background)
bg %1
# フォアグラウンドに戻す(fg = foreground)
fg %1
# ジョブ番号を省略するとカレントジョブ(+マーク)が対象
fg
プロセスの終了
# ジョブ番号で終了
kill %1
# PIDで終了
kill 12345
# 強制終了(通常の kill で終わらない場合)
kill -9 12345
# シグナルの種類
# SIGTERM (15): 終了要求(デフォルト)。プロセスが後処理できる
# SIGKILL (9) : 強制終了。後処理なしに即終了
nohup — ターミナルを閉じても動かし続ける
通常、ターミナルを閉じると(HUP シグナルが送られ)バックグラウンドプロセスも終了します。nohup を使うと HUP シグナルを無視させられます。
# nohup で実行(出力は nohup.out に保存される)
nohup ./long_process.sh &
# 出力先を指定する場合
nohup ./long_process.sh > output.log 2>&1 &
プロセスの確認
# 自分のジョブ一覧
jobs -l # -l でPIDも表示
# 実行中の全プロセス
ps aux
# プロセス名で絞り込み
ps aux | grep nginx
# リアルタイムで確認
top
htop # 見やすいUIのtop(別途インストールが必要)
実践:バックグラウンド実行のよくあるパターン
# ログを流しながらバックグラウンドでビルドを実行
nohup make build > build.log 2>&1 &
tail -f build.log # 別ターミナルでログを監視
# 複数の処理を並列実行
./process_a.sh &
./process_b.sh &
wait # 全バックグラウンドジョブが終わるまで待つ
echo "全処理完了"
まとめ
| コマンド | 覚えておくべきポイント |
|---|---|
find |
-exec {} + で検索と処理を一発で。スペース含むファイルは -print0 | xargs -0
|
grep |
-E で正規表現、-r で再帰検索、-B/-A で前後の文脈表示 |
awk |
$1 $2 でフィールド参照、END{print sum} で集計 |
sed |
s/old/new/g で置換、-i でファイル直接編集 |
| ジョブ管理 |
& で投げて jobs で確認、fg/bg で切り替え、長時間処理は nohup か tmux
|
この5つを組み合わせるだけで、日常のサーバー作業やログ解析の効率がぐっと上がります。ぜひ試してみてください。