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