- 1列目と3列目のみ表示
$ awk '{print $1,$3}'
- 末尾から3列目を表示
$ awk '{print $(NF - 2)}'
- 区切り文字を","として1列目のみ表示
$ awk -F, '{print $1}'
- 1列目と3列目以外を表示(行頭、行末に無駄な空白を入れずに)
$ awk '{for(i=1;i<=NF;i++) if(i!=1 && i!=3) printf (i>2 ? OFS : "") $i ; printf "\n"}'
- 一行目のヘッダが特定の文字列から始まる列のみ表示(行頭、行末に無駄な空白を入れずに)
# 一行目のヘッダが"hoge"から始まる列のみ表示(行頭、行末に無駄な空白を入れずに)
$ awk 'NR==1 {for(i=1;i<=NF;i++) if($i~/^hoge/) a[i]=1} {s=0; for(i=1;i<=NF;i++) if(a[i]) printf (s++ ? OFS : "") $i ; printf "\n"} '
# 以下は例
$ cat test5.txt
foo1 hoge2 bar3 hoge4 foo5
1 2 3 4 5
a b c d e
$ awk 'NR==1 {for(i=1;i<=NF;i++) if($i~/^hoge/) a[i]=1} {s=0; for(i=1;i<=NF;i++) if(a[i]) printf (s++ ? OFS : "") $i ; printf "\n"} ' test5.txt
hoge2 hoge4
2 4
b d
- 特定のパターンにマッチする行のみ表示
# hogehogeにマッチする行を表示
$ awk '/hogehoge/'
$ awk '$0 ~ /hogehoge/'
$ awk '{if($0~/hogehoge/) print}'
- 空行をスキップする
$ awk 'NF'
$ awk '/./'
$ awk '!/^$/'
- "START"と"END"に挟まれた行を表示
$ awk '/^START$/,/^END$/'
# 以下は例
$ cat test8.txt # テストデータ
hogehoge1
START
foo3
bar4
hogehoge5
bar7
END
foo9
$ awk '/^START$/,/^END$/' test8.txt
START
foo3
bar4
hogehoge5
bar7
END
- "START"と"END"に挟まれた行以外を表示
$ awk '/^START$/,/^END$/ {next} {print}'
- 2行目から4行目だけを表示
$ awk 'NR==2,NR==4'
$ awk 'NR>=2 && NR<=4'
- 3列目が"hogehoge"にマッチする行のみ表示
$ awk '$3 ~ /hogehoge/'
- 3列目が"hogehoge"に一致する行のみ表示
$ awk '$3 == "hogehoge"'
- ファイルの末尾から4行を表示(tailやheadは使わずに)
$ awk '{buf[i]=$0; i=(i+1)%4;} END{for(j=0;j<4;j++) print buf[(j+i)%4];}'
- はじめに"--start--"、終わりに "--end--"と表示
$ awk 'BEGIN{print "--start--"} {print} END{print "--end--"}'
# 例)
$ cat test13.txt # テストデータ
math english
10 20
30 40
50 60
70 80
$ awk 'BEGIN{print "--start--"} {print} END{print "--end--"}' test13.txt
--start--
math english
10 20
30 40
50 60
70 80
--end--
- 2行目以降の1列目の合計を計算して最後に表示する
$ awk 'NR>=2 {s+=$1} END{print s}'
# 例)
$ cat test14.txt # テストデータ
math english
10 20
30 40
50 60
70 80
$ awk 'NR>=2 {s+=$1} END{print s}' test14.txt
160
- 2行目以降の1列目の平均を計算して最後に表示する
$ awk 'NR>=2 {s+=$1;c++} END{print s/c}'
- 2行目以降の1列目の最大値を計算して最後に表示する
$ awk 'NR>=2 {if($1>a) a=$1} END{print a}'
- 一行目の各フィールドを配列に入れて表示
$ awk 'NR==1 {cnt=split($0, a); for(i=1;i<=cnt;i++) {print a[i]}}'
# 例)
$ cat test17.txt # テストデータ
math english
10 20
30 40
50 60
70 80
$ awk 'NR==1 {cnt=split($0, a); for(i=1;i<=cnt;i++) {print a[i]}}' test17.txt
math
english
- 空白で区切られた文字列の出現回数を各文字列ごとに表示 (uniqコマンドは使わずに)
$ awk '{for(i=1;i<=NF;i++) a[$i]++} END{for(i in a) {print i":"a[i]}}'
# 例)
$ cat test18.txt # テストデータ
apple banana lemon
grape orange cherry peach pear strawberry
orange
$ awk '{for(i=1;i<=NF;i++) a[$i]++} END{for(i in a) {print i":"a[i]}}' test18.txt
orange:2
apple:1
strawberry:1
pear:1
banana:1
grape:1
lemon:1
cherry:1
peach:1
$
説明:aは連想配列。
- 各行の6文字目以降を捨てる
$ awk '{print substr($0, 1, 5)}'
- 各行の最初の10文字を捨てる
$ awk '{print substr($0, 11)}'
- 行末から10文字を表示
$ awk '{print substr($0, length($0)-9, 10)}'
- 1列目は文字列"id"以降の部分を5文字だけ抜き出し、他の列はそのまま出力する
awk '{$1 = substr($1, index($1, "id"), 5); print}'
# 例)
$ cat test22.txt # テストデータ
iid001id9 orange a b c
$ awk '{$1 = substr($1, index($1, "id"), 5); print}' test22.txt
id001 orange a b c
- 1列目の'-'をすべて'/'に置換する
$ awk '{gsub("-", "/", $1); print}'
- 2列目の最初の'-'を'/'に置換する
$ awk '{sub("-", "/", $2); print}'
- 3列目の2番目の'-'を'/'に置換する
$ awk '{$3 = gensub("-", "/", 2, $3); print}'
- 各行の最後から2番目の'-'だけ'/'に置換する
$ awk '{s=$0; cnt=gsub("-", "/", s); if(cnt>=2) $0 = gensub("-", "/", cnt - 1, $0); print}'
- 各行の5文字目だけaに置換する
$ awk '{print gensub(/./, "a", 5, $0)}'
- 各行の末尾から5文字目から3文字をhogehogeに置換する
$ awk '{print substr($0, 1, length($0)-5) gensub(/^.../, "hogehoge", 1, substr($0, length($0)-4))}'
- 2列目のアルファベットをすべて大文字にする
$ awk '{$2=toupper($2); print}'
- "(数値)k" となっているところを"(数値)K" に置換する(後方参照)
$ awk '{print gensub(/([0-9]+)k/, "\\1" "K", "g", $0)}'
# 例)
$ cat test30.txt # テストデータ
10k 20m 30k ok
$ awk '{print gensub(/([0-9]+)k/, "\\1" "K", "g", $0)}' test30.txt
10K 20m 30K ok
参考