```{eval-rst} .. index:: single: CLI; awk single: 検索&置換したい; awk ``` # awk ```console $ awk '条件 { 処理 }' ファイル名 ``` `awk`コマンドで、ファイルの中身を、任意の条件で簡単に抽出できます。 とても強力なツールのようなので、沼にハマるとやばそうな気がします。 ここでは、条件を満たす列や行を選択したり、出力を整形したりする方法を紹介します。 :::{note} コマンド名は「オーク」と読みます。 Alfred **A**ho、Peter **W**einberger、Brian **K**ernighanの3人の開発者名に由来するそうです。 Kernighanは「プログラミング言語C」のK&RのKのひとです。 ::: ## ファイルを表示したい(`print`) ```console // 全行を表示 $ awk '{ print }' ファイル名 // 行番号を追加 $ awk '{ print NR, $0 }' ファイル名 // 2行目から表示 $ awk 'NR>1 { print }' ファイル名 ``` `print`関数で文字列を表示できます。 :::{note} ファイル名の代わりにパイプした標準出力を受け取り、 表示形式を加工する使い方が多いです。 ::: ## 特定のフィールドを表示したい(`$1 $2 ...`) ```console // 1列目を表示 $ awk '{ print $1 }' ファイル名 // 2列目を表示 $ awk '{ print $2}' ファイル名 // カラムの順番を入れ替える $ awk '{ print $1 $3 $2}' ファイル名 // 全行を表示 $ awk '{ print $0 }' ファイル名 ``` `$N`でフールド(=列番号)を抽出して表示できます。 ## 変数したい(`awk -v`) ```console $ awk -v date=$(date +%Y-%m-%d) '{ print date "," $0}' ファイル名 ``` `-v`オプションで変数名を定義できます。 ## CSV形式に変換したい ```console $ awk '{ print $1 "," $2 "," $3 }' ファイル名 > 変換後のファイル名.csv // 空白は詰めてもOK $ awk '{print $1","$2","$3}' ``` スペース区切り(もしくはタブ区切り)のファイルを、カンマ区切りに変換できます。 `$1`などのフィールド変数はそのままでOKですが、 `,`を文字としてクォートする必要があるため注意が必要です。 ## ディスク容量をしりたい ```bash #!/usr/bin/env set -euo pipefail ISO8601=$(date +%Y-%m-%dT%H:%M:%S%z) df --output | awk -v date="${ISO8601}" '{ print $1 "," $2 "," $5 }' > disk_usage.csv exit 0 ``` [df](./command-df.md)コマンドの出力をCSV形式に変換したときのサンプルです。 ## 空白とカンマで区切りたい(`-F`) ```console $ awk -F'[ ,]+' '{ print $1, $2, $3, ...}' ``` `-F`オプションで区切り文字を変更できます。 デフォルトは空白のみですが、カンマを追加したい場合も多々あります。 `[ ,]+`で空白もしくはカンマで区切ることができます。