我想要組合(邏輯或)兩個 awk 表達式。兩者分開工作都很好。第一個表達式印出搜尋詞之前的行。第二個表達式僅列印包含特殊字元的行。如果我透過 OR 運算子組合 bothe 表達式,我會收到錯誤'
^ 意外的換行符或字串結尾
'
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
閱讀您的要求,您描述二不同的表達方式兩個不同的工作。你說 :
First expression prints the line right before the search term
Second expression just prints the line that contains a special character
這意味著這兩個表達式不能以 OR 形式組合。您可以與 OR 表達式組合來執行相同的操作。
因此,根據您的措辭,正確答案是:
$ awk '/\*/{print a}{a=$0}/\→/' <<<"$a"
foo
bar→
bar→
foo
bar→
foo
bar→
bar→
如果您確實需要使用 OR 條件以便對兩個不同的條件執行相同的操作,您也可以這樣做:
awk '/[*→]/{print a; a=$0}' file
答案2
關於印刷的註釋以前的看到星號時會出現一條線,並且目前的當看到→
:
awk '/\*/ {print prev} /\→/ {print} {prev=$0}' file.txt
/pattern/ {action}
是 的縮寫$0 ~ /pattern/ {action}
。如果行上有星號,第一個操作將列印變量prev
,如果行上有箭頭,第二個操作將列印當前行,最後,我們無條件地將目前行儲存到prev
,以便在下一行符合時可用於列印。
答案3
這應該有效:
awk '/\*/ || /→/ {print}' /path/to/file
答案4
這給出了您引用的預期結果。不需要轉義 *,因為我們可以依賴「在 POSIX awk 和 gawk 中,'*'、'+' 和 '?'當正規表示式中沒有任何內容位於運算符之前時,運算符就代表自己。此處的行為,更多詳細資訊位於https://www.gnu.org/software/gawk/manual/gawk.html#Regexp
$ awk '/*/||/→/' file.txt
foo*
bar→
bar→
foo**
bar→
foo*
bar→
bar→
$
使用 grep 代替:
$ grep -E '\*|→' file.txt