テキスト処理
sed と awk
ストリームを行単位で置換・削除する sed と、列を扱う小さな言語 awk。よく使う形に絞って紹介。
sed行を置換・削除する
ファイルやテキストの文字列を置き換えたり、特定の行を消したりします。複数のファイルをまとめて書き換えるのにも使います。
sed [オプション] '<スクリプト>' [ファイル...]| オプション | 意味 |
|---|---|
-i | ファイルを直接書き換える(-i.bak で元をバックアップ) |
-n | 自動で出力しない(p で出したい行だけ出す) |
-E | 拡張正規表現を使う(+ ? () | がそのまま使える) |
-e | スクリプトを複数指定する |
置換
$ sed 's/foo/bar/' file.txt # 各行の最初の foo を bar に
$ sed 's/foo/bar/g' file.txt # すべての foo を bar に
$ sed -i 's/http:/https:/g' *.html # ファイルを直接書き換える
$ sed -i.bak 's/DEBUG=1/DEBUG=0/' .env
$ sed 's#/usr/local#/opt#g' paths.txt # 区切りは / 以外でもよい
$ sed -E 's/([0-9]+)-([0-9]+)/\2-\1/' dates.txt # グループを入れ替える行を選ぶ・消す
$ sed -n '10,20p' file.txt # 10〜20行目だけ表示
$ sed -n '/START/,/END/p' log.txt # START から END までの範囲
$ sed '/^#/d' config.conf # # で始まる行(コメント)を消す
$ sed '/^\s*$/d' file.txt # 空行を消す
$ sed '1d' data.csv # 1行目を消す
$ sed -i '$a\最後に追加する行' file.txt
$ sed -i '1i\先頭に入れる行' file.txtawk列を扱う
awk は、入力を1行ずつ読み、空白で区切った列を $1 $2 … として扱います。$0 は行全体、NF は列の数、NR は行番号です。
awk '条件 { 処理 }' [ファイル...]$ ps aux | awk '{print $2, $11}' # 2列目(PID)と11列目(コマンド)
$ awk -F: '{print $1}' /etc/passwd # : 区切りの1列目
$ awk -F, 'NR > 1 {print $3}' data.csv # 見出し行を飛ばして3列目
$ awk '$3 > 100' data.txt # 3列目が100より大きい行
$ awk '/ERROR/ {n++} END {print n}' app.log # ERROR の行数
$ awk '{sum += $5} END {print sum}' access.log # 5列目の合計
$ awk '{print $NF}' file.txt # 各行の最後の列
$ awk '!seen[$0]++' list.txt # 順番を保ったまま重複を除く
$ df -h | awk 'NR==1 || $5+0 > 80' # 使用率80%超えのディスク(見出しも)| 変数 | 意味 |
|---|---|
$0 | 行全体 |
$1 $2 … | 1列目・2列目… |
NF / $NF | 列の数 / 最後の列 |
NR | 何行目か |
FS / -F | 入力の区切り文字 |
OFS | 出力の区切り文字(-v OFS=, で指定) |
$ awk -F, -v OFS='\t' '{print $2, $1}' data.csv # CSV の列を入れ替えてタブ区切りに
$ awk '{printf "%-20s %5d\n", $1, $2}' stats.txt # 幅を揃えて表示