awkでエスケープ文字を含むbash変数を使用してファイルから行を抽出する

awkでエスケープ文字を含むbash変数を使用してファイルから行を抽出する

私は2つのパターンに基づいてファイルからいくつかの行を抽出するためのbashスクリプト(bash学習)を書いています。最初のパターンはコロンで終わる文です。 2番目のパターンは*N(この場合は58)回繰り返されます。

サンプルファイル:

lines I don not want
lines I don not want
lines I don not want

A sentence here:
********************************************************
lines I want
lines I want
lines I want
**********************************************************

lines I don not want
lines I don not want
lines I don not want

希望の出力:

A sentence here:
********************************************************
lines I want
lines I want
lines I want
**********************************************************

明示的にawk呼び出しを58回入力すると、スクリプトを機能させることができA sentence hereますが、清潔さと読みやすさのために次のことを好みます。\*

pat1="A sentence here"
pat2=`printf -- '\*%.s' {1..58} ; echo`
pat2=${pat2//\\/\\\\}
awk -v pat1="${pat1}" -v pat2="${pat2}" '/{pat1}/ {p=1}; p; /{pat2}/ {p=0}' $1

最初の位置変数は入力ファイルです。上記のコードは何も返しません。最初は交換せずに試しましたが、警告が表示されpat2ました。

awk: warning: escape sequence `\*' treated as plain `*'

私はこのコマンドを何千回も実行する必要があり、理想的にはクリーンで効率的なソリューションが必要です。私はawk使用法に全く依存しません。

編集する:

awkに手動でパターンを入力しても警告メッセージが表示されることがわかりました。おそらく変数をawkに正しく​​渡さなかったでしょう。

ベストアンサー1

ここにはいくつかのオプションがあります。

  • pat1、pat2は正規表現として扱われます。

    pat1="A sentence here"
    pat2='\*{58}'
    export pat1 pat2
    awk '$0 ~ ENVIRON["pat1"], $0 ~ ENVIRON["pat2"]'
    

    mawk4.0.0より前のバージョンは拡張正規表現演算子をgawkサポートしていないことに注意してください。{}以前のバージョンでは、環境変数を渡して認識できるようにすることがgawkできます。POSIXLY_CORRECT

    ここではその方法を使用しますが、タグ方法を使用して同じ操作を実行start-condition, end-condition [{action}]できます。p

  • pat1、pat2は固定文字列として扱われます。

    pat1="A sentence here"
    pat2=$(printf '*%.0s' {1..58})
    export pat1 pat2
    awk 'index($0, ENVIRON["pat1"]), index($0, ENVIRON["pat2"])'
    

    ここでindex()検索してください(可変内容)のどこでも大きな干し草の山(現在のレコード(行))ですが、単純な行全体の比較も実行できます。

    awk '"" $0 == ENVIRON["pat1"], "" $0 == ENVIRON["pat2"]'
    

    (合計が両方とも数値の場合でも""文字列比較が強制されます。)$0ENVIRON["patx"]

特定のCエスケープシーケンス(、、、...)がこれを処理する-vため、バックスラッシュ文字を含む可能性のあるデータを渡さないでください。したがって、バックスラッシュをエスケープする必要があります(GNU 4.2以降の場合、awk\n\b\\awkで始まり@/終わる値/も問題)。このように渡された変数も同様ですawk '...code...' awkvar="$shellvar"。使用ENVIRONまたはARGV交換してください。

バラよりこの関連質問への回答もっと学ぶ。

おすすめ記事