Linuxテキスト処理コマンド入門|grep・sed・awkの使い方を実例で解説

kento_morota 18分で読めます

Linuxの真の力は、テキスト処理にあると言っても過言ではありません。ログファイルの解析、設定ファイルの一括修正、CSVデータの加工——こうした日常的なタスクを効率的にこなすために欠かせないのが、grep・sed・awkの3つのテキスト処理コマンドです。

「grepで検索はできるけど、正規表現が難しい」「sedで置換したいがオプションがよくわからない」「awkは名前は聞くが使ったことがない」——そんなIT担当者・エンジニアの方に向けて、本記事ではgrep・sed・awkの使い方を豊富な実例とともに基礎から解説します。

Linuxの基本についてはLinuxとは?を、基本コマンドの全体像はLinuxコマンド一覧・実践ガイドをあわせてご覧ください。

テキスト処理コマンドを学ぶ前に知っておくべき基礎

grep・sed・awkを効果的に使うために、まずLinuxのテキスト処理の考え方を理解しましょう。

パイプとリダイレクト

Linuxのテキスト処理コマンドは、パイプ(|)で連結して使うことで真価を発揮します。各コマンドが小さな処理を担当し、パイプでデータを受け渡していくのがLinux流の処理スタイルです。

# パイプでコマンドを連結
cat access.log | grep "ERROR" | awk '{print $1, $4}' | sort | uniq -c | sort -rn

# リダイレクトで結果をファイルに保存
grep "ERROR" access.log > errors.txt

# リダイレクトで結果を追記
grep "WARNING" access.log >> errors.txt

正規表現の基本

テキスト処理コマンドでは正規表現(Regular Expression)を使ったパターンマッチングが頻繁に登場します。最低限知っておくべき正規表現のメタ文字を確認しましょう。

  • .(ドット): 任意の1文字にマッチ
  • *: 直前の文字の0回以上の繰り返し
  • +: 直前の文字の1回以上の繰り返し(拡張正規表現)
  • ^: 行頭にマッチ
  • $: 行末にマッチ
  • [abc]: a、b、cのいずれか1文字にマッチ
  • [0-9]: 数字1文字にマッチ
  • \d: 数字1文字(一部のツール)
  • \s: 空白文字
  • (): グループ化(拡張正規表現)
  • |: OR条件(拡張正規表現)

grep — テキスト検索の基本

grep(Global Regular Expression Print)は、テキストの中から指定したパターンにマッチする行を検索・抽出するコマンドです。最も使用頻度の高いテキスト処理コマンドと言えます。

grepの基本的な使い方

# ファイル内でパターンを検索
grep "error" /var/log/syslog

# 大文字小文字を区別しない検索
grep -i "error" /var/log/syslog

# 行番号を表示
grep -n "error" /var/log/syslog

# マッチした行数をカウント
grep -c "error" /var/log/syslog

# マッチしない行を表示(反転マッチ)
grep -v "DEBUG" /var/log/syslog

# 複数ファイルから検索
grep "error" /var/log/*.log

# ディレクトリを再帰的に検索
grep -r "TODO" /home/user/project/

# ファイル名のみ表示
grep -l "error" /var/log/*.log

# マッチした前後の行も表示
grep -A 3 "error" /var/log/syslog    # 後ろ3行
grep -B 3 "error" /var/log/syslog    # 前3行
grep -C 3 "error" /var/log/syslog    # 前後3行

grepの正規表現

# 行頭がErrorで始まる行
grep "^Error" /var/log/syslog

# 行末が.confで終わる行
grep "\.conf$" filelist.txt

# IPアドレスのパターン(基本正規表現)
grep "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" access.log

# 拡張正規表現を使用(-E または egrep)
grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" access.log

# OR条件での検索
grep -E "error|warning|critical" /var/log/syslog

# 単語単位でマッチ(部分一致を防ぐ)
grep -w "error" /var/log/syslog    # "errors"にはマッチしない

# 固定文字列として検索(正規表現を無効化)
grep -F "192.168.1.1" access.log

grepの実務活用例

# SSH不正ログインの試行を調査
grep "Failed password" /var/log/auth.log | tail -20

# 特定の時間帯のログを抽出
grep "Mar 22 1[0-4]:" /var/log/syslog

# 設定ファイルからコメントと空行を除外して表示
grep -v "^#" /etc/nginx/nginx.conf | grep -v "^$"

# プロセスの検索(grep自身を除外)
ps aux | grep "[n]ginx"

# ソースコード内のTODOコメントを検索
grep -rn "TODO\|FIXME\|HACK" --include="*.py" /home/user/project/

ログファイルの調査方法はLinuxログ管理入門でさらに詳しく解説しています。

sed — ストリームエディタによるテキスト変換

sed(Stream Editor)は、テキストストリームを行単位で編集・変換するコマンドです。ファイルを開かずに文字列の置換、削除、挿入ができるため、スクリプトによる一括処理に最適です。

sedの基本的な使い方(置換)

# 基本的な文字列置換(各行の最初のマッチのみ)
sed 's/old/new/' file.txt

# 各行のすべてのマッチを置換(gフラグ)
sed 's/old/new/g' file.txt

# 大文字小文字を無視して置換(iフラグ)
sed 's/error/ERROR/gi' file.txt

# 置換結果をファイルに直接書き込み(-iオプション)
sed -i 's/old/new/g' file.txt

# バックアップを作成しつつ直接書き込み
sed -i.bak 's/old/new/g' file.txt

# 特定の行のみ置換(3行目のみ)
sed '3s/old/new/g' file.txt

# 行範囲を指定して置換(5〜10行目)
sed '5,10s/old/new/g' file.txt

# パターンにマッチする行のみ置換
sed '/pattern/s/old/new/g' file.txt

sedの行操作

# 特定の行を削除(5行目を削除)
sed '5d' file.txt

# 行範囲を削除(1〜3行目を削除)
sed '1,3d' file.txt

# パターンにマッチする行を削除
sed '/^#/d' file.txt             # コメント行を削除
sed '/^$/d' file.txt             # 空行を削除
sed '/^#/d; /^$/d' file.txt     # コメント行と空行を削除

# 特定の行の前後に行を挿入
sed '3i\新しい行をここに挿入' file.txt    # 3行目の前に挿入
sed '3a\新しい行をここに追記' file.txt    # 3行目の後に追記

# 特定のパターンにマッチする行の後に行を追加
sed '/\[server\]/a\new_setting = value' config.ini

sedの実務活用例

# 設定ファイルの値を一括変更
sed -i 's/listen 80/listen 8080/g' /etc/nginx/sites-available/default

# IPアドレスの一括変更
sed -i 's/192\.168\.1\.100/10\.0\.0\.50/g' config.conf

# ファイルのBOMを除去(UTF-8 BOM付きファイルの修正)
sed -i '1s/^\xEF\xBB\xBF//' file.txt

# 複数の置換を一度に実行
sed -e 's/foo/bar/g' -e 's/baz/qux/g' file.txt

# 特定の範囲のテキストを抽出(10〜20行目)
sed -n '10,20p' file.txt

# パターンにマッチする行のみ表示
sed -n '/ERROR/p' /var/log/syslog

# CSVの特定の列を変換
sed 's/,old_value,/,new_value,/g' data.csv

# HTMLタグの除去
sed 's/<[^>]*>//g' page.html

# 行頭にプレフィックスを追加
sed 's/^/PREFIX: /' file.txt

# 行末に文字列を追加
sed 's/$/ # end/' file.txt

sedでの正規表現グループ参照

# キャプチャグループと後方参照
# 日付フォーマットの変換(YYYY-MM-DD → DD/MM/YYYY)
sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/' dates.txt

# ファイル名の一括変更用リストの生成
ls *.jpg | sed -E 's/(.*)\.jpg/mv \1.jpg \1.png/'

# 重複するスペースを1つに統合
sed -E 's/ +/ /g' file.txt

awk — 高度なテキスト処理とデータ抽出

awkは、テキストをフィールド(列)単位で処理する強力なプログラミング言語です。grepが「行の検索」、sedが「行の変換」に特化しているのに対し、awkは列の操作とデータの集計・加工に威力を発揮します。

awkの基本的な使い方

# 特定のフィールド(列)を出力
# $1=第1列, $2=第2列, $0=行全体
awk '{print $1}' file.txt
awk '{print $1, $3}' file.txt

# フィールドの区切り文字を指定(-F)
awk -F: '{print $1, $3}' /etc/passwd     # コロン区切り
awk -F, '{print $1, $2}' data.csv        # カンマ区切り
awk -F'\t' '{print $1, $2}' data.tsv     # タブ区切り

# 出力フォーマットの指定
awk '{printf "%-20s %s\n", $1, $2}' file.txt

awkのパターンマッチング

# 条件に合う行のみ処理
awk '/ERROR/ {print $0}' /var/log/syslog

# 特定のフィールドが条件を満たす行のみ処理
awk '$3 > 100 {print $1, $3}' data.txt

# 文字列比較
awk '$1 == "admin" {print $0}' users.txt

# 複合条件
awk '$3 > 100 && $4 == "active" {print $1, $3}' data.txt

# 正規表現でフィールドを検索
awk '$2 ~ /^192\.168/ {print $0}' access.log

# 否定マッチ
awk '$2 !~ /^10\./ {print $0}' access.log

awkの組み込み変数

# NR: 現在の行番号
awk '{print NR, $0}' file.txt             # 行番号付きで表示

# NF: 現在の行のフィールド数
awk '{print NF, $0}' file.txt             # フィールド数付きで表示

# $NF: 最後のフィールド
awk '{print $NF}' file.txt                # 各行の最後の列を表示

# FS: フィールドセパレータ(-Fと同じ)
awk 'BEGIN{FS=":"} {print $1}' /etc/passwd

# OFS: 出力フィールドセパレータ
awk -F: 'BEGIN{OFS=","} {print $1, $3, $6}' /etc/passwd

awkのBEGIN/ENDブロック

# BEGINブロック: データ処理前に実行
# ENDブロック: データ処理後に実行
awk 'BEGIN{print "=== レポート ==="} {print $0} END{print "=== 合計: " NR "行 ==="}' file.txt

# 数値の合計を計算
awk '{sum += $3} END{print "合計:", sum}' data.txt

# 平均値の計算
awk '{sum += $3; count++} END{print "平均:", sum/count}' data.txt

# 最大値と最小値
awk 'NR==1{max=min=$3} $3>max{max=$3} $3

awkの実務活用例

# /etc/passwdからユーザー情報を抽出
awk -F: '$3 >= 1000 {print $1, $3, $6}' /etc/passwd

# Nginxアクセスログからステータスコード別集計
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

# ディスク使用率が80%を超えるパーティションを抽出
df -h | awk 'NR>1 && int($5)>80 {print $6, $5}'

# CSVファイルの特定列の合計
awk -F, '{sum += $4} END{printf "合計: %d\n", sum}' sales.csv

# プロセスのメモリ使用量上位10件
ps aux | awk 'NR>1 {print $4, $11}' | sort -rn | head -10

# IPアドレス別のアクセス数を集計
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -20

# 時間帯別のアクセス数を集計
awk '{print substr($4, 14, 2)}' access.log | sort | uniq -c

# 特定のフィールドを使ってCSVを再構成
awk -F, 'BEGIN{OFS=","} {print $3, $1, $5}' input.csv > output.csv

ユーザー管理の情報はLinuxユーザー・グループ管理で詳しく解説しています。

grep・sed・awkを組み合わせた実践テクニック

3つのコマンドをパイプで組み合わせることで、複雑なテキスト処理も効率的に実行できます。

ログ解析の実践例

# Webサーバーのエラー分析パイプライン
# 1. 500エラーの行を抽出 → 2. IPアドレスを取得 → 3. 集計 → 4. 上位10件
grep " 500 " access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -10

# 特定の時間帯のエラーログから原因を分析
grep "Mar 22 1[0-2]:" /var/log/syslog | grep -i "error" | \
  awk '{for(i=5;i<=NF;i++) printf "%s ", $i; print ""}' | \
  sort | uniq -c | sort -rn | head -10

# SSHブルートフォース攻撃の検知
grep "Failed password" /var/log/auth.log | \
  awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | \
  awk '$1 > 10 {print "警告: " $2 " から " $1 " 回の失敗"}'

設定ファイルの一括操作

# 複数の設定ファイルで特定のパラメータを一括変更
find /etc/nginx/sites-available/ -name "*.conf" -exec \
  sed -i 's/worker_connections 768/worker_connections 1024/g' {} \;

# 設定ファイルから有効な設定行のみ抽出(コメントと空行を除外)
grep -v "^#" /etc/nginx/nginx.conf | grep -v "^$" | sed 's/^[[:space:]]*//'

# 設定ファイルの差分確認用に整形
sed '/^#/d; /^$/d; s/[[:space:]]*$//' config.old > /tmp/old_clean
sed '/^#/d; /^$/d; s/[[:space:]]*$//' config.new > /tmp/new_clean
diff /tmp/old_clean /tmp/new_clean

データ変換の実践例

# CSVからTSVへの変換
sed 's/,/\t/g' data.csv > data.tsv

# JSONライクな形式への変換
awk -F, 'NR>1 {printf "{\"name\": \"%s\", \"age\": %s, \"city\": \"%s\"}\n", $1, $2, $3}' data.csv

# 列の入れ替え
awk -F, 'BEGIN{OFS=","} {print $3, $1, $2}' data.csv

# 重複行の検出
awk 'seen[$0]++ == 1' file.txt

# 特定パターンの行の間のテキストを抽出
sed -n '/^START/,/^END/p' file.txt

その他の便利なテキスト処理コマンド

grep・sed・awkと組み合わせて使われることの多い補助的なテキスト処理コマンドも押さえておきましょう。

sort — ソート

# アルファベット順にソート
sort file.txt

# 数値順にソート
sort -n file.txt

# 逆順ソート
sort -r file.txt

# 特定の列でソート(3列目を数値順)
sort -k3 -n file.txt

# 人間が読みやすいサイズ表記でソート(1K, 2M, 3G等)
sort -h file.txt

uniq — 重複の処理

# 連続する重複行を除去(事前にsortが必要)
sort file.txt | uniq

# 重複回数をカウント
sort file.txt | uniq -c

# 重複している行のみ表示
sort file.txt | uniq -d

# ユニークな行のみ表示(重複なし)
sort file.txt | uniq -u

cut — 列の切り出し

# 区切り文字を指定して列を切り出し
cut -d: -f1,3 /etc/passwd

# 文字位置で切り出し
cut -c1-10 file.txt

# タブ区切りの特定列
cut -f2,4 data.tsv

tr — 文字変換

# 小文字を大文字に変換
tr 'a-z' 'A-Z' < file.txt

# 特定の文字を削除
tr -d '\r' < windows_file.txt > unix_file.txt    # CR(改行コード変換)

# 連続する空白を1つにまとめる
tr -s ' ' < file.txt

wc — 行数・単語数・バイト数のカウント

# 行数をカウント
wc -l file.txt

# 単語数をカウント
wc -w file.txt

# パイプと組み合わせ
grep "ERROR" /var/log/syslog | wc -l

まとめ

Linuxのテキスト処理コマンドは、サーバー管理と開発の生産性を大きく左右するスキルです。本記事で解説した内容を振り返りましょう。

  • grepはパターンマッチングによるテキスト検索の基本ツール。正規表現と組み合わせて強力な検索が可能
  • sedはストリームエディタとして、ファイルを開かずに文字列の置換・削除・挿入ができる
  • awkはフィールド(列)単位の処理とデータ集計に優れ、簡易的なプログラミングが可能
  • 3つのコマンドをパイプで連結することで、複雑なテキスト処理を効率的に実行できる
  • sort、uniq、cut、tr、wcなどの補助コマンドと組み合わせることで処理の幅がさらに広がる

テキスト処理のスキルは、ログ管理シェルスクリプトの作成、パフォーマンスモニタリングなど、あらゆるLinux運用の場面で活躍します。これらのコマンドに慣れるコツは、実際のファイルを使って繰り返し練習することです。

Linuxのテキスト処理をさらに効率化するには、Vimエディタの使い方も学んでおくと良いでしょう。基本を体系的に学びたい方はLinuxコマンド一覧・実践ガイドもぜひご活用ください。

#Linux#テキスト処理#grep
共有:
無料メルマガ

週1回、最新の技術記事をお届け

AI・クラウド・開発の最新記事を毎週月曜にメールでお届けします。登録は無料、いつでも解除できます。

プライバシーポリシーに基づき管理します

AI活用のヒントをお探しですか?お気軽にご相談ください。

まずは話だけ聞いてもらう