パイプで区切られたファイルから特定のパターンが存在する部分文字列を抽出したいので、以下のコマンドを使用しました、
awk -F ":" '/REWARD REQ. SERVER HEADERS/{print $1, $2, $3, $4}' sample_profile.txt
ここで、 'REWARD REQ。 SERVER HEADERS 'はファイル内で検索されるパターンであり、コロンで区切られた行に最初の4つの部分を印刷します。
ここで、bash変数を送信してパターンとして機能させたいと思います。したがって、以下のコマンドを使用しましたが、機能していません。
awk -v pat="$pattern" -F ":" '/pat/{print $1, $2 , $3, $4 } sample_profile.txt
どうすれば_-v
および-F
単一のawk
コマンドで?
ここでの問題は、-F
とは関係ありません。
問題は、pat
を変数にしたいときに/pat/
を使用することです。 /pat/
と言うと、awk
はそれをリテラルの "pat"として理解するため、文字列 "pat"を含む行との一致を試みます。
変数を介してパターンを提供する場合は、次のように~
を使用する必要があります。
awk -v pat="$pattern" '$0 ~ pat'
すべてをまとめると、コードは次のようになります。
awk -v pat="$pattern" -F ":" '$0~pat{print $1, $2, $3, $4 }' file
# ^^^^^^
例を参照してください。
このファイルが与えられた場合:
$ cat file
hello
this is a var
hello bye
「hello」を含む行を探しましょう。
$ awk '/hello/' file
hello
hello bye
次に、変数に含まれる「pat」を探してみてください。
$ awk -v pat="hello" '/pat/' file
$ # NO MATCHES!
$0 ~ pat
式を使用してみましょう。
$ awk -v pat="hello" '$0~pat' file
hello # WE MATCH!
hello bye
もちろん、このような式を使用して、1つのフィールドだけを照合し、awk -v pat="$pattern" '$2 ~ pat' file
などと言うことができます。
GNU Awkユーザーズガイド→3.1正規表現の使用方法 :
正規表現が/ foo /のようにスラッシュで囲まれている場合、5.27が数値定数であり、「foo」が文字列定数であるように、正規表現と呼びます。
GNU Awkユーザーズガイド→3.6動的正規表現の使用 :
「〜」または「!〜」演算子の右側は、正規表現定数(つまり、スラッシュ間の文字列)である必要はありません。任意の式を使用できます。式は評価され、必要に応じて文字列に変換されます。文字列の内容は正規表現として使用されます。この方法で計算された正規表現は、動的正規表現または計算された正規表現と呼ばれます。
BEGIN { digits_regexp = "[[:digit:]]+" } $0 ~ digits_regexp { print }
これは、digits_regexpを1つ以上の数字を記述する正規表現に設定し、入力レコードがこの正規表現と一致するかどうかをテストします。
awk -v pat="$pattern" -F":" '$0 ~ pat { print $1, $2, $3, $4 }' sample_profile.txt
正規表現の//
表記内で変数を使用することはできません(pat
の検索と区別する方法はありません)。 ~
(マッチング)演算子を使用して、変数が正規表現であることを指定する必要があります。
これは一種のハックですが、私にとっては少し簡単になります。
cmd="awk '/$pattern/'"
eval $cmd
最初に文字列にすることで、awkの境界を越えて操作できます