bashにおけるawkコマンドの基本
awkについて調べながら勉強したので、個人的にまとめてみました
awkは入力として受け取った文字列に対して、フィールド区切り文字やレコード区切り文字を指定して、
「列」に対する処理を行うためのコマンドです。また、awk単体としても、1つのプログラムです。
awkの基本書式
awk -F'[フィールド区切り文字(複数可能)]' -v '変数=xx' '{awkコマンド}' file
- 今回は標準出力を行うawkコマンド「print」を利用し、awkで指定したフィールドを取得します
awkで1フィールド目を取り出すコマンドは、「print $1」です
1フィールド目を出力 print $1
オプションである -F'[フィールド区切り文字]' を指定しない場合、
区切り文字には、タブまたは半角スペースが選択されます
echo からパイプで渡してみます
echo 1 2 3 4 |awk '{print $1}'
1
2フィールド目を出力 print $2
echo 1 2 3 4 |awk '{print $2}'
2
$0は「パイプやファイルから渡された、文字列全て」という意味です print $0
printのみも、一緒
echo 1 2 3 4 |awk '{print $0}'
1 2 3 4
echo 1 2 3 4 |awk '{print}'
1 2 3 4
フィールド区切り文字に「:」を指定してみます
1フィールド目を出力
echo 1:2:3:4 |awk -F'[:]' '{print $1}'
1
2フィールド目を出力
echo 1:2:3:4 |awk -F'[:]' '{print $2}'
2
フィールド区切り文字は複数指定できます
フィールド区切り文字に「:」と「/」を指定
ならべて書くことで、「:」と「/」の1つ1つがフィールド区切り文字として扱われます
echo 1:2/3:4 |awk -F'[:/]' '{print $3}'
3
##複数フィールドの出力 print $1,$2
print $1,$2 のようにカンマで区切って記述します
複数フィールドの出力は、半角スペースで区切られます
これは、OFSを指定していないため ※OFSについては後述します
echo 1:2/3:4 |awk -F'[:/]' '{print $1,$2}'
1 2
OFS
「OFS」は、Output Field Separatorの略で、awkの組み込み変数であり、「出力のフィールド区切り文字」を指定します
下記では「#」を指定し、フィールドの出力を「#」で区切ります
また、「-v」 はvariable(変数)を指定する、という意味のオプションです
-v '変数=xx'
という形式で記述します
-F'[フィールド区切り文字]'で、「入力のフィールド区切り文字」については指定しますが、これは、処理で一番よく使われるためオプション化されているだけ、という違いです。
echo 1:2/3:4 |awk -F'[:/]' -v 'OFS=#' '{print $1,$3}'
1#3
RS
RSはRecord Separatorの略で、awkの組み込み変数です
「入力のレコード区切り文字」を指定、下記では「/」を指定します
レコードは「/」を区切り文字にして、「1:2」と「3:4」に分けられます
「/」をレコード区切り文字にして、各々のレコードから1フィールド目を取得します
出力は改行で区切って出力されます ※これはORSが指定されていないため ORSは下述
echo 1:2/3:4 |awk -F'[:]' -v 'RS=/' '{print $1}'
1
3
echo 1:2/3:4 |awk -F'[:]' -v 'RS=/' '{print $1,$2}'
1 2
3 4
# フィールド区切り文字とレコード区切り文字で同じ文字がある場合、レコード区切り文字が優先されます
echo 1:2/3:4 |awk -F'[:/]' -v 'RS=/' '{print $1,$2}'
1 2
3 4
ORS
「ORS」は、Output Record Separatorの略で、awkの組み込み変数であり、「出力のレコード区切り文字」を指定します
下記では「This is ORS」を指定し、レコードの出力を区切ります
echo 1:2/3:4 |awk -F'[:/]' -v 'RS=/' -v 'ORS=This is ORS' '{print $1,$2}'
1 2This is ORS3 4
OFSとORSを明示します
OFSは空白4つ、ORSは改行2つにしてみます
\n は改行
echo 1:2/3:4 |awk -F'[:/]' -v 'OFS= ' -v 'RS=/' -v 'ORS=\n\n' '{print $1,$2}'
1 2
3 4
最終フィールドを取り出す変数として$NFが用意されています
echo 1:2/3:4 |awk -F'[:/]' '{print $NF}'
4
echo 1:2/3:4 |awk -F'[:/]' '{print $NF-1}'
3
printの他に、printfもつかえます
echo 1:2/3:4 |awk -F'[:/]' '{printf "%s\n%s\n",$NF,$NF-1}'
4
3