Linux awkコマンド

参考資料

  1. Linux awkコマンドの詳細
  2. [初心者向け]Awkの基本的な使い方
  3. awkコマンドの実践的な使用方法
  4. 阮一峰_awk 初心者ガイド
  5. 8つの強力なAwk組み込み変数
  6. AWK組み込み関数

1. オプション設定

1.1 基本パラメータ

  • -F:フィールドセパレータの指定 awk -F',' '{ print $1 }' file はコンマ区切りで処理。
  • -f:スクリプトファイルの指定 awk -f handle.awk filehandle.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 フィールドセパレータ
  • FSBEGIN{}内に設定
  • 複数区切りは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}'

タグ: awk Linuxコマンド テキスト処理 シェルスクリプト データ抽出

7月26日 17:23 投稿