awk:透過邏輯或組合表達式

awk:透過邏輯或組合表達式

我想要組合(邏輯或)兩個 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

相關內容