プロジェクト

全般

プロフィール

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 }'

関数いろいろ

関数名 機能
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." の箇所が、"AzulSystem,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桁で左詰に書式します。- を入れないと右詰になります。


約1ヶ月前に更新