awkの範囲パターンに変数を渡す

awkの範囲パターンに変数を渡す

awkでスコープモードを使用しようとしています。

grep -a volume somefile | awk '/^Apr 25 23:44:04*/,/^Apr 26 12:44:01*/ {print}'

これはうまくいきますが、日付と時刻を変数に入れて次のように実行しようとすると、次のようになります。

time1="Apr 25 23:44:04"
time2="Apr 26 12:44:01"
grep -a volume somefile | awk '/^"$time1"*/,/^"$time2"*/ {print}'

ベストアンサー1

シェル変数は一重引用符で囲まれた文字列内にあるため、拡張されません。一重引用符で囲まれた文字列の中に二重引用符が含まれているかどうかは重要ではなく、一重引用符で囲まれた文字列です。

代わりに使用してください:

grep -a volume somefile | awk "/^$time1/,/^$time2/ {print}"

実はprintそうだから基本タスクは次のように単純化できます。

grep -a volume somefile | awk "/^$time1/,/^$time2/"

このアプローチは本当に注意してください。意図しないawkアクティブ文字が含まれていないことを確認する必要がありますtime1time2

より安全なアプローチは、シェル変数をawk変数に転送することです。

grep -a volume somefile | awk -v t1="$time1" -v t2="$time2" '($0~"^"t1),($0~"^"t2)'

Gillesがコメントで指摘したように、このより安全なアプローチを使用しても、まだ注意が必要です。との文字列time1に文字が含まれている場合、その文字列は正規表現として解釈されます。質問に表示されている文字列(正規表現アクティブ文字は含まれていません)では問題になりませんが、他の文字列に驚くべき結果が表示される場合はこれが原因である可能性があります。time2^*+.?\[|{$

おすすめ記事