トップページ > コンテンツ > コンピュータ関連その他 > UNIXコマンド > awk

■目次



コマンド記載形式

awk 'BEGIN{前処理(初期化や区切り文字指定等)} (パターン) {アクション(通常処理等)} END{後処理(出力処理等)}'

記載形式の要所ごとの解説

BEGIN{} 前処理部分。省略可能
(パターン) 条件絞込部分(grepに近い)。省略可能
正規表現記述や$1=="test"等の評価式を入れる。
正規表現は通常$0に対して行われるが、$1 ~ /正規表現/とすると、$1や$2に限定することもできる。(正規表現の否定は!~)
パターンの条件は&&や||で複合的にすることができる。
パターンは()で囲わなくてもパターンとして認識する。
{アクション} レコード数(≒行数)分繰り返し処理を行う部分。省略すると{print $0}になる模様。
END{} 後処理部分。省略可能

その他解説

  • BEGIN{}の前にfunction test(arg1){return arg1を加工}のように記載することで関数定義をしてawk内で使わせることも可能。
  • Linuxのshell変数を渡す場合は'"${変数}"'のようにすると良い。

よく使うオプション

v vオプションの後に「変数名=値」とすることで、後続処理に変数値を与えることもできる。
f fオプションの後にawkスクリプトを指定ことで、処理記述を外部スクリプトに任せることも可能。
F 区切り文字を指定。区切り文字が複数ある場合は[]で囲う。空白複数個等の場合は[ ]+で表現可能。

awk文法

c言語ライクに書くことができる。

組み込み変数

$0 レコード
$1,$2… レコードのX番目のフィールド。使用例(フィールドの1番目と2晩目の合計を表示):cat test.txt | awk '{print $1+$2}
NR 現在のレコード数。行番号。

■例:3行目だけを抽出したい場合:
head -n 3 | tail -n 1と書く所を、awk 'NR==3'のように表現可能。
■例:1行目〜3行目を抽出したい場合:
awk '(NR==1,NR==3){処理内容等}'のように記載できる
NF 現在のフィールド数。1行の内、何個のフィールド(単語的な意味合い)があるか。
RS 入力レコードの区切り文字
FS 入力フィールドの区切り文字。Fオプション(BEGIN{FS="区切り文字"}とほぼ同意)でも可。
ORS 出力レコードの区切り文字
OFS 出力フィールドの区切り文字

※他にもレコード(行)の区切り文字や、出力フィールドの区切り文字があるが、使用頻度が多くなさそうなので省略。確認したい場合はこちらのサイト参照。

組み込み関数

getline ファイルやパイプから1行読み込む。getline 変数名とすることで読み込んだ「次の行」を変数名に入れることができる。※awk '{getline 変数名;}'とした場合、2行目が入る点に注意。
match 正規表現が最初に出る位置。match(文字列,正規表現)。RSTARTに正規表現が合致した開始位置、RLENGTHにそこからの長さを格納する
split 文字列を配列に分解。split(分解する文字列,分解後の格納配列,分解するための区切り文字)
index 文字が最初に出る位置。index(文字列,開始文字)
sprintf 書式に従って表示
substr 部分文字列を返す。substr(文字列,開始番目,長さ)

※他にも算術処理等があるが、使用頻度が多くなさそうなので省略。確認したい場合はこちらのサイト参照。

※多くのプログラミングのようなゼロオリジンでなく、1から数え始める感じなので注意。

※getlineはNRの値も更新してしまうので注意。
例えば、
/*test.txt*/
1行目データ
2行目データ
3行目データ

/*実行コマンドと実行結果*/
cat test.txt | awk 'BEGIN{getline}{print NR}'
2
3

ちなみにそうしたくない場合は、以下のようにすると回避できた。
cat test.txt | awk '{getline 変数名; printf("%s",変数名);}や
cat test.txt | awk '{getline 変数名;}END{print 変数名;}'

コマンド具体例

1.テキストファイルから任意文字を抽出

awk 'BEGIN { print "*** begin ***"}(/hoge/){ print $1} END { print "*** end ***"}' test.txt

(出力結果)
*** begin ***
hogehoge
hogehoge2
*** end ***

※test.txtの中身が下記の場合
hogehoge hogedesu
test
sample
hogehoge2

2.組込関数を使ったコマンド具体例

/*test.txt*/
xxx:yyy
/*test.txtからyyyを抽出するコマンド*/
例1:cat test.txt | awk '{split($0,arr,":"); print arr[1]}
例2:cat test.txt | awk '{print substr($0,index($0,":")+1)}'
例3:cat test.txt | awk 'match($0,/:(.*)/){print substr($0, RSTART+1, RLENGTH)}'

3.ログを解析する

3-1.ログのunix時間を見やすい時刻に変更する。
https://qiita.com/todaemon/items/1003021309a6bf28d463参照

3-2.logから特定時刻のみを抽出
/*xxx.log*/
YYYY-MM-DD HH:MM:SS.XXX logtext1
YYYY-MM-DD HH:MM:SS.XXX logtext2
 
/*logファイルから、特定時刻の物のみを抽出するコマンド*/
例1:
cat xxx.log | ¥
awk '($1 ~ /YYYY-MM-DD/ ) { 
   split($2,array,":"); 
   if(array[1] >=8 && array[1] <= 10){
     print $0
   }
}'
とすると、YYYY-MM-DDで8時〜10時のログが取れる。
最終更新:2019年06月22日 14:57