web-dev-qa-db-ja.com

awkの変数で指定されたパターンと一致させる方法は?

パイプで区切られたファイルから特定のパターンが存在する部分文字列を抽出したいので、以下のコマンドを使用しました、

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コマンドで?

19

ここでの問題は、-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つ以上の数字を記述する正規表現に設定し、入力レコードがこの正規表現と一致するかどうかをテストします。

35
fedorqui
awk -v pat="$pattern" -F":" '$0 ~ pat { print $1, $2, $3, $4 }' sample_profile.txt

正規表現の//表記内で変数を使用することはできません(patの検索と区別する方法はありません)。 ~(マッチング)演算子を使用して、変数が正規表現であることを指定する必要があります。

6

これは一種のハックですが、私にとっては少し簡単になります。

cmd="awk '/$pattern/'"
eval $cmd

最初に文字列にすることで、awkの境界を越えて操作できます

0
Ryan Donahoe