順番に読み進めながら学べます

awk — フィールド抽出

awk '{print $1}' で列を、$NFで最後の列を取り出し、-F',' で区切りをカンマに変える書き方、NRとNF、/error/{print $2} で一致行だけ処理するパターンを、図解とブラウザ端末で確認します。

列を取り出す — $1 / $NF / -F

awkは行を空白区切りで列(フィールド)に分け、列ごとに処理できるコマンドです。awk '{print $1}'のように書くと、各行の1列目だけを取り出して表示します。{}の中に、各行へ行う処理(ここではprint)を書きます。$1は1列目、$2は2列目を表し、$0は行全体を指します。

$NFは最後の列を表す特別な書き方です。NFは1行の列数を持つ変数で、$NFと書くとその行の最後の列になります。列数が行ごとに違っても、常に末尾の列を取り出せます。区切りが空白でないときは-F','のように-Fで区切り文字を指定します。区切り文字はクォートで囲むと安全です(-F',')。

printf 'alice 30 tokyo\nbob 25 osaka\n' > users.txt   # 素材を作成
awk '{print $1}' users.txt                              # 1 列目 alice と bob
awk '{print $2}' users.txt                              # 2 列目 30 と 25
awk '{print $NF}' users.txt                             # 最後の列 tokyo と osaka
printf 'alice,30\nbob,25\n' > csv.txt                  # カンマ区切りの素材
awk -F',' '{print $1}' csv.txt                          # 区切りをカンマにして 1 列目
awk の列の数え方
alice30tokyo$1 = alice$2 = 30$NF = tokyo (最後)
$1は1列目、$NFはその行の最後の列を指します。
書き方意味
$11 列目を取り出すawk '{print $1}' users.txt
$22 列目を取り出すawk '{print $2}' users.txt
$NF最後の列を取り出すawk '{print $NF}' users.txt
$0行全体を取り出すawk '{print $0}' users.txt
-F','区切り文字をカンマに変えるawk -F',' '{print $1}' csv.txt
NR現在の行番号awk '{print NR, $0}' nf.txt
NFその行の列数awk '{print NF}' nf.txt
/pat/{print $1}pat に一致する行の1列目を出すawk '/error/{print $1}' log.txt

printf 'alice 30 tokyo\nbob 25 osaka\n' > users.txtで空白区切りの素材を作成してください。

cat users.txtで中身を確認してください。

awkで各行の1列目だけを表示してください。

④ 続けて、awk '{print $2}' users.txtで各行の2列目だけを表示してください。

⑤ さらに、最後の列を表す書き方で各行の末尾の列を表示してください。

printf 'alice,30\nbob,25\n' > csv.txtでカンマ区切りの素材を作成し、区切り文字を指定するオプションを付けて1列目を表示してください。(正しく実行できれば解説が表示されます)

Linux console
0 / 7 実行済み
Loading Linux Terminal...

行番号と列数 — NR / NF

NRは現在処理している行の番号、NFはその行の列数を持つ組み込み変数です。awk '{print NR, $0}'と書くと、各行の前に行番号を付けて行全体を出せます。awk '{print NF}'なら各行が何列に分かれたかが分かります。

printf 'red\ngreen blue\n' > nf.txt   # 素材を作成
awk '{print NR, $0}' nf.txt             # 1 red / 2 green blue
awk '{print NF}' nf.txt                 # 1 行目は 1 列、2 行目は 2 列

printf 'red\ngreen blue\n' > nf.txtで列数の違う2行の素材を作成してください。

awkで行番号を表す変数と行全体を組み合わせ、各行の前に行番号を付けて表示してください。

③ 続けて、列数を表す変数を表示し、1行目と2行目で列数が違うことを確認してください。

Linux console
0 / 3 実行済み
Loading Linux Terminal...

一致行だけを処理する — /pat/{print ...}

awkはプログラムの前にパターンを書くと、一致した行だけにそのプログラムを適用します。awk '/error/{print $1}'errorを含む行に限って1列目を出します。grepが行を丸ごと表示するのに対し、awkは一致行から必要な列だけを取り出せます。

パターンで一致行だけを処理する
awk '{print $1}' f全行の1列目を出すawk '/error/{print $1}' ferror を含む行の1列目だけ
プログラム前のパターンで処理対象の行を絞り込めます。
printf 'error disk\ninfo start\nerror cpu\n' > log.txt   # 素材を作成
awk '/error/{print $2}' log.txt                            # error 行の 2 列目 disk と cpu

printf 'error disk\ninfo start\nerror cpu\n' > log.txtで素材ファイルを作成してください。

awkでプログラムの前にパターンを書き、errorを含む行だけに対して2列目を表示してください。

③ 出力された語がerrorの行から取り出された列だけになっていることを確認してください。

grep error log.txtも実行し、grep は行全体・awk は2列目だけが出ることを見比べてください。

Linux console
0 / 3 実行済み
Loading Linux Terminal...
QUIZ

理解度チェック

まずは1問ずつ答えてみましょう。

Q1awk '{print $1}' fは何を出力しますか?

Q2区切り文字をカンマに変えてawkを使うときに付けるオプションはどれですか?

Q3awk '/error/{print $1}' fはどの行を処理しますか?