rokkonet

PC・Androidソフトウェア・アプリの開発・使い方に関するメモ

awkコマンドの書式

2021 Feb. 25.
2021 Feb. 11.

参考元 IBM Knowledge Center
    awk で動的に正規表現を変更する方法のメモ | 毎日の向こうに
    The GNU Awk User's Guide - 正規表現

基本構文

awk -F "フィールド区切り文字" -v 変数1=hoge1 -v 変数2=hoge2  'パターン{BEGINパターン時の初期化}{各行アクション}END{アクション}' FILE.txt
    ## シェル変数は -vオプションでawk上の変数に置き換える。-v var="${HOGE}"

文字列リテラルの記述は二重引用符で囲む(シングルクォートではダメ)

"abc"

-Fオプションへのnull文字/ヌル文字の指定には $'\0' ではなく $"\0" とする

awk -F $"\0" '{print $2 }'

-Fオプションに指定する区切り文字が2文字以上の時は正規表現と扱われる

参考サイト AWK のフィールドセパレータの真実 - Qiita

文字列の連結演算子は半角スペース

print $1 $3 "hoge"    ## 引数が連結されて出力される
print $1, $3, "hoge"    ## カンマで区切ると引数が半角スペースで区切られて1行に出力される

変数の初期化と利用

awk 'var=1 { ++var }'

シェル変数の値をフィールド番号として受け取り、そのフィールド番号のフィールド値を出力

Num=5
ps a | awk -v FNumber=$Num '{print $FNumber}'

デフォルトのフィールド区切り文字(フィールド・デリミタ)は空白とタブ文字と改行

cutコマンドと違い、区切り文字には2文字以上の文字列が許される。
-F "\t" と指定するとタブ文字のみで区切られる。
-F " " と半角スペースを指定すると空白とタブ文字の両方で区切られる。
空白のみを区切りとし、タブ文字で区切らないようにするには、「対象テキスト内の空白をアンダースコアにして、区切り文字をアンダースコアにする」等の工夫を要する。

アクション部の複数コマンドは;(セミコロン)で区切る

awk ' { コマンド1 ; コマンド2 } '

条件式の記述

if文はアクション部に記述する。

awk ' { 条件式 コマンド } '
awk ' { 条件式 { コマンド1 ; コマンド2 } } '    // 複数コマンドは;(セミコロン)で区切る

awk ' { if ( 条件 ) コマンド1 else コマンド2 } '
awk ' { if ( 条件 ) { コマンド1; コマンド2 } } '
awk ' { if ( 条件 ) { コマンド1; コマンド2 } else { コマンド3 ; コマンド4 } '

awk '{if (FNR == 1) print}' FILE.txt    ## FNRは現在行の番号

パターンに指定できるもの

正規表現
awk '/hoge/ {print}' FILE.txt
    ## 正規表現hogeに一致する行を出力
正規表現文字列部分に変数を記述する場合(動的正規表現
echo "Str1" | awk -v SearS="${SeachStr}" -v AdS="${AddStr}" 'BEGIN {RegExp="^"SearS } {if ($0 ~ RegExp) {print $0 "---" AdS} else {print $0}}'
  ## -vオプションを利用して検索文字列シェル変数をawkに渡す
  ##    検索文字列とする文字列シェル変数SeachStrをawk変数SearSとする
  ##    マッチした行に追記する文字列シェル変数AddStrをawk変数AdSとする
  ## 先頭に変数SearSがある行を検索する
  ##    RegExp="^"SearSとして動的正規表現RegExpをセットする
  ##    awkでは、変数は引用符を付けたりせずそのまま記述する。文字列リテラルは二重引用符で囲む。
  ##    正規表現のメタ文字も二重引用符で囲む
  ## Stringの動的正規表現とのマッチ確認は if (String ~ DynamicRegExp) { } とする

関係式
awk '$1 =! "abc" {print}' FILE.txt
    ## 最初のフィールドがabcでない行を出力


次の2つは同じ機能

cat FILE | awk '$5 == "hoge" {print}'    // 関係式
cat FILE | awk '{if ($5 == "hoge") print}'    // 条件文

パターンの組み合わせ
awk '/ab/,/xy/ {print}' FILE.txt
    ##  , (コンマ) で区切った 2 つのパターンについて、最初のパターンと一致するレコードで始まるすべてのレコードに対して実行され、2 番目のパターンと一致するレコードまで (このレコードを含む) 続く
BEGIN パターンと END パターン
awk 'BEGIN{ i=0 } { print ++i,$0 } END{ print "(" i "行)" }' FILE.txt
    ## BEGIN パターンで指定したアクションは、入力を読み取る前に実行され、 END パターンで指定したアクションは、すべての入力を読み取った後で実行される