sedとawkを使いこなす!テキスト処理の基礎と実践ワンライナー
sedとawkの基本から応用まで。置換、抽出、集計などテキスト処理の実践的なワンライナーを多数紹介。シェルスクリプト初心者にもわかりやすく解説。
sedとawkとは?
sed(ストリームエディタ)とawk(パターン処理言語)は、UNIX系OSでテキスト処理に欠かせないコマンドです。シェルスクリプトやワンライナーで頻繁に使われ、ログ解析、設定ファイルの編集、データ整形などに威力を発揮します。
sedは主に「置換」「削除」「挿入」などの編集操作をストリーム(入力の流れ)に対して行います。awkは「パターンマッチング」「フィールド単位の処理」「集計」に強みがあります。
この記事では、実務で役立つ具体的なワンライナーを中心に、両者の使い分けや組み合わせ方も解説します。
sedの基本と実践ワンライナー
置換(sコマンド)
最もよく使うのがs/検索パターン/置換文字/フラグです。
<h1>各行の最初の'old'を'new'に置換</h1>
$ sed 's/old/new/' file.txt
<h1>すべての'old'を'new'に置換(gフラグ)</h1>
$ sed 's/old/new/g' file.txt
<h1>大文字小文字を区別しない(iフラグ)</h1>
$ sed 's/old/new/gi' file.txt
行の削除(dコマンド)
特定のパターンにマッチする行を削除します。
<h1>'error'を含む行を削除</h1>
$ sed '/error/d' file.log
<h1>5〜10行目を削除</h1>
$ sed '5,10d' file.txt
<h1>空行を削除</h1>
$ sed '/^$/d' file.txt
行の挿入・追加(i, a, cコマンド)
<h1>3行目の前に'INSERTED LINE'を挿入</h1>
$ sed '3i\INSERTED LINE' file.txt
<h1>最終行の後に'END'を追加</h1>
$ sed '$a\END' file.txt
<h1>5〜7行目を'REPLACED'に変更</h1>
$ sed '5,7c\REPLACED' file.txt
特定の行だけ編集
<h1>2〜5行目の'foo'を'bar'に置換</h1>
$ sed '2,5s/foo/bar/g' file.txt
<h1>'error'を含む行だけ'ERROR'に置換</h1>
$ sed '/error/s/error/ERROR/g' file.log
ファイルへの直接保存(-iオプション)
<h1>バックアップファイル(.bak)を作成して置換</h1>
$ sed -i.bak 's/old/new/g' file.txt
<h1>バックアップなしで上書き(GNU sed)</h1>
$ sed -i 's/old/new/g' file.txt
MacのBSD sedでは-i ''のように空文字列を指定します。
awkの基本と実践ワンライナー
フィールドの抽出
awkはデフォルトで空白またはタブで区切られたフィールドを$1, $2, ...で参照します。
<h1>2列目と4列目を表示</h1>
$ awk '{print $2, $4}' data.txt
<h1>カンマ区切りのファイル(-Fオプション)</h1>
$ awk -F',' '{print $1, $3}' data.csv
パターンマッチング
<h1>'error'を含む行だけ表示</h1>
$ awk '/error/' file.log
<h1>3列目が100より大きい行を表示</h1>
$ awk '$3 > 100' data.txt
<h1>1列目が'apple'の行の2列目を表示</h1>
$ awk '$1 == "apple" {print $2}' data.txt
集計処理
<h1>2列目の合計を計算</h1>
$ awk '{sum += $2} END {print sum}' data.txt
<h1>グループごとの集計(1列目でグループ化)</h1>
$ awk '{arr[$1] += $2} END {for (k in arr) print k, arr[k]}' data.txt
<h1>行数のカウント</h1>
$ awk 'END {print NR}' file.txt
条件分岐とループ
<h1>3列目が0より大きい行の1列目と3列目を表示、そうでなければスキップ</h1>
$ awk '{if ($3 > 0) print $1, $3}' data.txt
<h1>1列目が'apple'または'banana'の行</h1>
$ awk '$1 == "apple" || $1 == "banana"' data.txt
組み込み変数の活用
NR: 現在の行番号NF: 現在の行のフィールド数FS: フィールド区切り文字(デフォルトは空白)OFS: 出力フィールド区切り文字<h1>行番号付きで出力</h1>
$ awk '{print NR, $0}' file.txt
<h1>各フィールドをカンマ区切りで出力</h1>
$ awk '{OFS=","; print $1, $2, $3}' data.txt
<h1>フィールド数が3より多い行だけ表示</h1>
$ awk 'NF > 3' file.txt
sedとawkの組み合わせテクニック
複雑な置換と抽出
<h1>sedで特定の行だけを抽出し、awkでフィールド処理</h1>
$ sed -n '/^ERROR/p' log.txt | awk '{print $2, $4}'
<h1>awkで加工した結果をsedで整形</h1>
$ awk '{print $1, $2}' data.txt | sed 's/ /,/g'
パイプラインでの連携
<h1>ログファイルからエラー行を抽出し、タイムスタンプとエラーコードを取得</h1>
$ grep 'ERROR' app.log | awk '{print $1, $3}' | sed 's/\[/ /; s/\]//'
<h1>CSVの特定列を集計し、結果をカンマ区切りに変換</h1>
$ awk -F',' '{sum[$1] += $2} END {for (k in sum) print k, sum[k]}' sales.csv | sed 's/ /,/g'
実践的なユースケース
ログファイルの解析
<h1>アクセスログからステータスコード200の行を抽出し、URLと応答時間を表示</h1>
$ awk '$9 == 200 {print $7, $NF}' access.log
<h1>エラーログの件数を集計</h1>
$ grep 'ERROR' app.log | awk '{print $1}' | sort | uniq -c | sort -rn
設定ファイルの編集
<h1>nginxの設定でポート番号を変更</h1>
$ sed -i 's/listen 80;/listen 8080;/' /etc/nginx/sites-available/default
<h1>コメント行を削除</h1>
$ sed -i '/^#/d' config.ini
データの整形
<h1>スペース区切りをタブ区切りに変換</h1>
$ sed 's/ */\t/g' data.txt
<h1>数値の書式を整える(awkで小数点以下2桁に丸める)</h1>
$ awk '{printf "%s %.2f\n", $1, $2}' data.txt
注意点とベストプラクティス
-i)。スクリプトを書くときは環境を意識しましょう。/を使う場合は、別の区切り文字(s#old#new#)を使うと読みやすくなります。まとめ
sedとawkは、テキスト処理の強力な武器です。ワンライナーで簡単な処理をサッと書けるようになると、シェル作業の効率が格段に向上します。最初は基本の置換とフィールド抽出から始め、徐々に集計や条件分岐に挑戦してみてください。パイプラインで組み合わせることで、さらに複雑な処理も可能です。
この記事で紹介したワンライナーを実際に試しながら、自分なりの便利な組み合わせを見つけてください。