Awk: 渡された Bash 変数を列値と比較

Awk: 渡された Bash 変数を列値と比較

次の例を使用してください。

#submission,date
"test1","22 April 2024"
"test2","24 April 2024"
"test3","25 March 2024"
"test6","01 April 2023"
"test7","02 April 2022"
"test8","03 April 2021"

この記事を書く時点で、2024年4月の月のテストだけを印刷したいと思います。次のコマンドを試してください。

awk -F, -v date="$(date +'%B %Y')" '/^[^#]/ && $2 ~ /'$date'\"$/{print $1}' tests.csv

すべてのテストを印刷します。 Awkを使ってBash変数を比較するには?

答え1

情報How are variables ...- 思考、コード、質問で「変数」が何を意味するかを非常に明確に説明してください。シェル、bashでawkを呼び出しています。 Bashはawkではありません。 2つの完全に独立したツールで、それぞれ独自の構文、意味、範囲を持ちます。そして変数

あなたのコードには次のものがあります。

awk -v date="$(date +'%B %Y')"

塗りつぶすawk変数はシェル変数ではなく、他のUnixツールへの呼び出し出力を含みますdate

awkと同様に、Cawkでは名前のみを使用して変数の値を取得できますが、シェルでは値を$取得するには変数名の前にaを入れる必要があります。したがって、コードの次の部分は次のようになります。

$2 ~ /'$date'\"$/

dateawk変数の値を取得するにはこれを使用する必要がありますdateが、2番目の問題が発生します。内部で使用します。リテラル正規表現区切り文字がありますが、変数と文字列で正規表現を構成する必要が/.../あるためdate\"$動的正規表現文字通りの正規表現はありません。これを考慮すると、コードのこの部分は次のようになります。

$2 ~ (date "\"$")

これを考慮すると、スクリプトは次のようになります。

$ awk -F, -v date="$(date +'%B %Y')" '/^[^#]/ && $2 ~ (date "\"$"){print $1}' tests.csv
"test1"
"test2"

dateしかし、私は最初の初期化で正規表現を作成するために接続します。

awk -F, -v date="$(date +'%B %Y')\"$" '/^[^#]/ && $2 ~ date{print $1}'

または次のBEGINセクションで:

awk -F, -v date="$(date +'%B %Y')" 'BEGIN{date=date "\"$"} /^[^#]/ && $2 ~ (date "\"$"){print $1}'

したがって、文字列の連結は比較的遅い操作なので、入力行ごとに一度だけ発生しません。

GNU awkがある場合、もう1つのオプションは保存することです。強力な形式の正規表現定数変数の動的正規表現文字列の代わりにdate:

awk -F, -v date="@/$(date +'%B %Y')[^\"]+\"$/" '/^[^#]/ && $2 ~ date{print $1}' file

または:

awk -F, -v d="$(date +'%B %Y')" 'BEGIN{date=@/x[^"]+"$/; sub(/x/,d,date)} /^[^#]/ && $2 ~ date{print $1}' file

しかし、2番目はやや不思議になります。普通で古い動的正規表現は、特定のケースでうまく機能します。

awkスクリプトでシェル変数の値を実際に使用するには、次を参照してください。awkスクリプトでシェル変数を使用する方法どうすればいいですか?

関連情報