Awk¶
- 目次
- Awk
UNIX/Linux系に搭載されているテキスト処理系 awk の使い方メモ。
機能¶
入力¶
セパレーターの指定¶
-F
オプションでセパレーターを指定できます。
- 1文字を指定した場合はその文字がセパレーター
awk -F, ...
カンマ文字をセパレーターに指定 - 2文字以上を指定した場合は正規表現となる
awk -F'[;,=]'
セミコロン、カンマ、=をそれぞれセパレーターに指定
行数¶
先頭行を除外¶
awk 'NR>1 { print $1 }'
- NRには行番号が入るので、それで1行目より後を指定する
行マッチング¶
正規表現にマッチした行を処理対象¶
先頭が空白または数字で開始する行を対象とする¶
awk '/^[ 0-9].*/{ print $1 }'
指定した列の文字列が数値の行を対象とする¶
3列目が数値の時、
awk '$3 ~ /[0-9]+/ { print $3 }'
複数条件にマッチした行¶
awk '$1 ~ /[A-Z]+/ && $3 ~ /[0-9]+/ { print $0 }'
正規表現を使わない指定¶
1フィールド目が特定の文字列に一致awk '$1 == "WWW" {print $2}'
関数いろいろ¶
関数名 | 機能 | 例 |
---|---|---|
length(文字列) | 文字列の文字数を返却 | length($1) |
split(文字列, 出力配列名, セパレータ文字) | 文字列をセパレータ文字で分割し出力ファイル名に格納 | split($3, array, "_") アンダースコアで文字列を分割し配列arrayに格納 |
制御いろいろ¶
if文などの制御を記載予定
出力¶
カンマセパレートで出力¶
awkは、print関数でカンマ区切りで複数の項目を指定すると、変数OFSに定義されたセパレータで区切って出力します。
awk -v 'OFS=,'
awk -F, 'BEGIN{OFS=,}{print $1, $3}'
変数の指定方法は、コマンドラインから、-vオプションで指定するか、アクションの最初に指定することができます。
実例¶
コマンドの出力から必要な情報を抜粋¶
java_homeの出力から抜粋する例¶
MacOSでは、インストールされているJDKの一覧を、/usr/libexec/java_home -V
で表示します。
~ % /usr/libexec/java_home -V Matching Java Virtual Machines (3): 21 (arm64) "Homebrew" - "OpenJDK 21" /opt/homebrew/Cellar/openjdk/21/libexec/openjdk.jdk/Contents/Home 17.0.8+7-LTS (arm64) "BellSoft" - "BellSoft Liberica JDK 17.0.8+7" /Library/Java/JavaVirtualMachines/liberica-jdk-17-full.jdk/Contents/Home 11.0.20.1 (arm64) "Azul Systems, Inc." - "Zulu 11.66.19" /Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home /opt/homebrew/Cellar/openjdk/21/libexec/openjdk.jdk/Contents/Home
上述のように、インストールされているJDKの数、インストールされているJDKの情報、現在のJAVA_HOME設定を表示します。JDKの情報は次の内容です。バージョン表記 (アーキテクチャ) "ディストリビュータ名" - "JDKディストリビューション名" インストールパス
java_home -V
の出力は、先頭行、JDK情報行は標準エラー出力、現在のJAVA_HOME設定は標準出力になります。
この表示から、先頭行、最終行を除くJDK情報から、バージョン表記、JDKディストリビューション名の2つを抜粋する処理を awk で記述します。
標準エラー出力だけをパイプでawkに渡す¶
~ % (/usr/libexec/java_home -V >/dev/null) 2>&1 | awk '{print $0}' Matching Java Virtual Machines (3): 21 (arm64) "Homebrew" - "OpenJDK 21" /opt/homebrew/Cellar/openjdk/21/libexec/openjdk.jdk/Contents/Home 17.0.8+7-LTS (arm64) "BellSoft" - "BellSoft Liberica JDK 17.0.8+7" /Library/Java/JavaVirtualMachines/liberica-jdk-17-full.jdk/Contents/Home 11.0.20.1 (arm64) "Azul Systems, Inc." - "Zulu 11.66.19" /Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home
- サブシェルで、標準出力を
>/dev/null
で捨て、その後標準エラー出力を2>&1
で標準出力に合流させます
先頭行を除外¶
~ % (/usr/libexec/java_home -V >/dev/null) 2>&1 | awk 'NR>1{print $0}' 21 (arm64) "Homebrew" - "OpenJDK 21" /opt/homebrew/Cellar/openjdk/21/libexec/openjdk.jdk/Contents/Home 17.0.8+7-LTS (arm64) "BellSoft" - "BellSoft Liberica JDK 17.0.8+7" /Library/Java/JavaVirtualMachines/liberica-jdk-17-full.jdk/Contents/Home 11.0.20.1 (arm64) "Azul Systems, Inc." - "Zulu 11.66.19" /Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home
- NR>1 で、行番号が1より大きい行を処理します
セパレーターの選択¶
デフォルトの空白で行の文字列を区切ると、ディストリビューター名が "Azul System, Inc."
の箇所が、"Azul
、System,
、Inc."
とに区切られてしまいます。そこで、ダブルクォートを区切り文字とします。
~ % (/usr/libexec/java_home -V >/dev/null) 2>&1 | awk -F'"' 'NR>1{print $1,$4}' 21 (arm64) OpenJDK 21 17.0.8+7-LTS (arm64) BellSoft Liberica JDK 17.0.8+7 11.0.20.1 (arm64) Zulu 11.66.19
-F'"'
で、ダブルクォートを区切文字に指定(ダブルクォート単独 @-F" ではダメ)
(アーキテクチャ)を除外¶
$1が、21 (arm64)
となるので、split関数で区切り文字を"("と指定し、区切り文字の前の文字列を取り出します。
~ % (/usr/libexec/java_home -V >/dev/null) 2>&1 | awk -F'"' 'NR>1{split($1, a, "("); print a[1], $4}' 21 OpenJDK 21 17.0.8+7-LTS BellSoft Liberica JDK 17.0.8+7 11.0.20.1 Zulu 11.66.19
書式を整形¶
printfで桁数を指定して表示します。
~ % (/usr/libexec/java_home -V >/dev/null) 2>&1 | awk -F'"' 'NR>1{split($1, a, "("); printf("%-20s%s\n", a[1], $4)}' 21 OpenJDK 21 17.0.8+7-LTS BellSoft Liberica JDK 17.0.8+7 11.0.20.1 Zulu 11.66.19
%-20s
は、文字列を20桁で左詰に書式します。-
を入れないと右詰になります。