awk: 論理ORで式を結合する

awk: 論理ORで式を結合する

2 つの awk 式を結合 (論理 OR) したいです。別々にすると両方とも正常に動作します。最初の式は検索語の直前の行を出力します。2 番目の式は特殊文字を含む行のみを出力します。両方の式を OR 演算子で結合すると、エラーが発生します '

^ 予期しない改行または文字列の終わり

'

awk '(({$0~/\*/; print a; a=$0}) || (/\→/))' file.txt

file.txt は次のようになります:

foo
*
bla
bla
bar→
bar→
foo
*
bla
bla
bar→
foo
*
bla
bar→
bar→

期待される結果:

foo
bar→
bar→
foo
bar→
foo
bar→
bar→

答え1

あなたの要件を読んで、あなたは次のように説明していますさまざまな表現2つの異なる仕事。 あなたは言う :

First expression prints the line right before the search term
Second expression just prints the line that contains a special character

つまり、これら 2 つの式は OR で組み合わせることはできません。同じアクションを実行する OR 式で組み合わせます。

結果として、あなたの言葉遣いによる正しい答えは次のようになります:

$ awk '/\*/{print a}{a=$0}/\→/' <<<"$a"
foo
bar→
bar→
foo
bar→
foo
bar→
bar→

2 つの異なる条件に対して同じアクションを実行するために OR 条件を実際に使用する必要がある場合は、次のようにすることもできます。

awk '/[*→]/{print a; a=$0}' file

答え2

印刷に関する注意事項前のアスタリスクが表示されたら、現在を見たときの行:

awk '/\*/ {print prev} /\→/ {print} {prev=$0}' file.txt

/pattern/ {action}はの略です$0 ~ /pattern/ {action}。最初のアクションは、prev行にアスタリスクがある場合は変数を出力し、2番目のアクションは矢印がある場合は現在の行を出力し、最後に無条件に現在の行を に保存しprev、次の行が一致する場合に印刷できるようにします。

答え3

これは動作するはずです:

awk '/\*/ || /→/ {print}' /path/to/file

答え4

これはあなたが引用した期待通りの結果をもたらします。* をエスケープする必要はありません。「POSIX awk と gawk では、正規表現にそれらの前に何もない場合は、'*'、'+'、および '?' 演算子はそれ自体を表します。」という動作に頼ることができるからです。詳細については、https://www.gnu.org/software/gawk/manual/gawk.html#正規表現

$ awk '/*/||/→/' file.txt
foo*
bar→
bar→
foo**
bar→
foo*
bar→
bar→
$

代わりに grep を使用します:

$ grep -E '\*|→' file.txt

関連情報