参考資料
- Linux awkコマンドの詳細
- [初心者向け]Awkの基本的な使い方
- awkコマンドの実践的な使用方法
- 阮一峰_awk 初心者ガイド
- 8つの強力なAwk組み込み変数
- AWK組み込み関数
1. オプション設定
1.1 基本パラメータ
-F:フィールドセパレータの指定awk -F',' '{ print $1 }' fileはコンマ区切りで処理。-f:スクリプトファイルの指定awk -f handle.awk fileは handle.awk 内のスクリプトを使用。-v:変数の定義と代入awk -v var=10 '{ print var }' fileで var を 10 に設定。BEGIN{}:初期化ブロック、全行処理前に行う。主にグローバル変数やFSの設定。//:パターンマッチング用のブロック(文字列または正規表現){}:コマンドブロック、複数のコマンドは;で区切るEND{}:終了ブロック、全行処理後に実行。集計結果の出力などに使用
awk [-F|-f|-v] 'BEGIN{} // {command1; command2} END{}' ./path/filename
1.2 組み込み変数
| 変数名 | 英語表記 | 説明 | デフォルト値 |
|---|---|---|---|
| $0 | 全体の内容 | ||
| $n | n番目のフィールド | ||
| FILENAME | ファイル名 | "-" | |
| RS | Record Separator | 行区切り | 改行(\n) |
| FS | Field Separator | フィールド区切り | スペース |
| ORS | Output Record Separator | 出力行区切り | \n |
| OFS | Output Field Separator | 出力フィールド区切り | スペース |
| NR | Number of Records | 現在の行数 | |
| NF | Number of Fields | 現在のフィールド数 | |
| $NF | 最終フィールド | ||
| $(NF-1) | 最終から2番目 |
1.3 組み込み関数
| 関数名 | 説明 |
|---|---|
| sub(regex, sub, string) | 文字列置換 |
| substr(str, start, l) | 部分文字列取得 |
| length(String) | 文字列長取得 |
| split(String, A, [Ere]) | 文字列分割 |
| tolower(String) | 小文字変換 |
| toupper(String) | 大文字変換 |
2. オプション例
2.1 -F フィールドセパレータ
2.1.1 単一区切り指定
⏹ price.csv
バナナ,100,ベトナム
リンゴ,200,カンボジア
パイナップル,500,フィリピン
- コンマ区切りで果物名が$1となる
awk -F"," '{print $1}' ./price.csv
2.1.2 複数区切り指定
-F"[,_]":区切り文字をリスト化
awk -F"[,_]" '{print $3}'
2.1.3 空白なし出力
awk -F":" '{print $1$3}' /etc/passwd
2.1.4 スペース区切り出力
awk -F":" '{print $1,$3}' /etc/passwd
2.1.5 明示的な空白挿入
awk -F":" '{print $1 " " $3}' /etc/passwd
2.1.6 フォーマット付き出力
awk -F":" '{print "User:" $1 "\t ID:" $3 }' /etc/passwd
2.2 -v 変数定義
⏹ data.txt
- タブ区切り
佐藤太郎 25
田中花子 22
鈴木一郎 30
-Fでタブ指定、-vで変数加算値=5を定義
cat data.txt | awk -F"\t" -v 加算値=5 '{print $1, $2 + 加算値}'
2.3 // パターンマッチ
⏹ log1.txt
2323 IN mmm 支払ID=5768 UUID=woenoo; 状態=成功 方法=paypay
2323 OUT COST=45726
2345 IN mmm 支払ID=34895 UUID=;ljkler 状態=失敗 方法=alipay
2345 OUT COST=34855
⏹ log2.csv
2323,IN,mmm,支払ID=5768,UUID=woenoo;,状態=成功,方法=paypay
2323,OUT,uuaa=5768,COST=45726
2345,IN,mmm,支払ID=34895,UUID=;ljkler,状態=失敗,方法=alipay
2345,OUT,COST=34855
2.3.1 行の包含/非包含
⏹ COSTを含む行抽出
cat log1.txt | awk '/COST/ {print $0}'
⏹ SEQOUTを含まない行抽出
cat log1.txt | awk '!/SEQOUT/ {print $0}'
2.3.2 複数キーワード同時含む
⏹ 支払IDと成功を含む行
cat log1.txt | awk '/支払ID/ && /成功/ {print $0}'
2.3.3 任意キーワード含む
⏹ 支払IDまたは2323を含む行
cat log1.txt | awk '/支払ID/ || /2323/ {print $0}'
2.3.4 行頭/行末マッチ
⏹ 2345で始まる行
cat log1.txt | awk '/^2345/ {print $0}'
⏹ pppで終わる行
cat log1.txt | awk '/ppp$/ {print $0}'
2.3.5 フィールドレベルのマッチ
⏹ 4番目フィールドに5768を含む行
cat log2.csv | awk -F"," '$4~/5768/ {print $0}'
⏹ 4番目フィールドに5768を含まない行
cat log2.csv | awk -F"," '$4!~/5768/ {print $0}'
2.4 {} コマンドブロック
2.4.1 条件分岐
- 括弧で条件を囲み、
ifは小文字必須
⏹ 4番目フィールドに5768を含み、5番目がuuid=woenoo;の行
cat log2.csv | awk -F"," '{if($4~/5768/ && $5=="uuid=woenoo;") print $0}'
2.4.2 BEGIN/ENDブロック
⏹ scores.csv
名前,点数
佐藤,95
田中,85
鈴木,75
山田,59
中村,82
佐々木,73
NR>1:ヘッダ行スキップBEGIN{}で変数初期化普通{}で集計END{}でフォーマット出力
cat scores.csv | awk -F"," 'BEGIN{優秀=0;普通=0;不合格=0} NR>1
{
if($2 >= 85) {優秀++}
else if($2 >= 60 && $2 < 85) {普通 ++}
else {不合格++}
}
END{printf "優秀:%d\n普通:%d\n不合格:%d\n", 優秀, 普通, 不合格}'
2.5 FS/RS
2.5.1 フィールドセパレータ
FSはBEGIN{}内に設定- 複数区切りは
FS="[,_]"形式
# 単一分離
echo "佐藤,田中,鈴木" | awk 'BEGIN{FS=","} {print $3}'
# 複数分離
echo "佐藤,田中_鈴木" | awk 'BEGIN{FS="[,_]"} {print $3}'
2.5.2 レコードセパレータ
⏹ users.txt
Alice,25
Bob,30
Charlie,22
- 行末にカンマ追加後、
RS=","で行単位を変更
cat users.txt | awk '{printf "%s,\n", $0}' | awk 'BEGIN{RS=","} {print $1}'
2.6 OFS 出力フィールドセパレータ
⏹ transactions.csv
トランID,識別子,決済方法,結果
110120,uuid=1234,pay=123alipay,result=success
256754,uuid=2332,pay=344alipay,result=fail
234556,uuid=7456,pay=869paypay,result=success
OFS="_"でフィールドをアンダースコア結合
cat transactions.csv | awk 'BEGIN{FS=","} NR==1 || $3~/alipay/
{
print NR, $1, (NR == 1 ? $3 : substr($3, 5, length($3) - 4))
}'
OFS="_"
2.7 NR 行番号
2.7.1 奇数行出力
ls -l ~/uwsgi-2.0.18/core/m*.c | awk 'NR % 2 == 1 {print "行"NR":", $0}'
2.7.2 3行目以降出力
ls -l ~/uwsgi-2.0.18/core/m*.c | awk 'NR > 3 {print "行"NR":", $0}'
2.7.3 行番号付加出力
awk '{print NR,$0}' /etc/passwd
2.7.4 メタデータ付き出力
awk -F: '{print NR, NF, $NF, "\t", $0}' /etc/passwd
2.7.5 5行目出力
awk -F: 'NR==5{print}' /etc/passwd
2.8 NF フィールド数
2.8.1 フィールド数出力
awk -F: '{print NF}' /etc/passwd
2.8.2 最終フィールド出力
awk -F: '{print $NF}' /etc/passwd
2.8.3 4フィールドのみ出力
awk -F: 'NF==4 {print }' /etc/passwd
2.8.4 フィールド数2以上出力
awk -F: 'NF > 2 {print $0}' /etc/passwd
2.8.5 2番目から最後
apluser@FengYeHong-HP:~$ echo '"1","2","3","4","5","6"'
"1","2","3","4","5","6"
apluser@FengYeHong-HP:~$ echo '"1","2","3","4","5","6"' | awk -F"," '{print NF}'
6
apluser@FengYeHong-HP:~$ echo '"1","2","3","4","5","6"' | awk -F"," '{print $NF}'
"6"
apluser@FengYeHong-HP:~$ echo '"1","2","3","4","5","6"' | awk -F"," '{print $(NF -1)}' | tr -d '"'
5
3. 組み込み関数
3.1 gsub() 全置換
⏹ fruits.csv
日本リンゴ,100,uuid=1223
中国リンゴ,200,uuid=3434
ベトナムリンゴ,59,uuid=2898
梨,50,uuid=8976
スイカ,56,uuid=9079
gsub()でリンゴをマーク付きに置換
# 2種類の記法
cat fruits.csv | awk 'BEGIN{FS=","} $1~/リンゴ/ && $2 > 99 {gsub("リンゴ","★リンゴ",$1); print $0}'
# &はマッチ内容を参照
cat fruits.csv | awk 'BEGIN{FS=","} $1~/リンゴ/ && $2 > 99 {gsub("リンゴ","★&",$1); print $0}'