今天我在網上搜索一個命令,在一個模式後面打印下兩行,並且遇到了一個我無法理解的awk命令。解釋awk命令
$ /usr/xpg4/bin/awk '_&&_--;/PATTERN/{_=2}' input
有人可以解釋嗎?
今天我在網上搜索一個命令,在一個模式後面打印下兩行,並且遇到了一個我無法理解的awk命令。解釋awk命令
$ /usr/xpg4/bin/awk '_&&_--;/PATTERN/{_=2}' input
有人可以解釋嗎?
奇妙的隱晦。時間允許時更新。
_
正被用作變量名稱。 &&
是一個邏輯運算符,它有兩個真正的動作一起運行。一旦_的值減小到零,則& &的後半部分爲假,並且不會生成輸出。
print -- "
xxxxx
yyyy
PATTERN
zzz
aa
bbb
ccc
ddd" | awk '_&&_--;/PATTERN/{_=2}'
輸出
zzz
aa
調試版本
print -- "
xxxxx
yyyy
PATTERN
zzz
aa
bbb
ccc
ddd" | awk '_&&_--;{print "_="_;print _&&_};/PATTERN/{_=2;print "_="_ }'
輸出
_=
0
_=
0
_=
0
_=
0
_=2
zzz
_=1
1
aa
_=0
0
_=0
0
_=0
0
_=0
0
簡單地說,在給定的正則表達式表達式匹配不包含匹配的行之後,該命令會打印多行。
行數在塊{_=2}
中指定,如果行匹配PATTERN
,則變量_
設置爲2。在匹配行之後讀取的每行都會導致_
遞減。您可以讀取_&&_--
,就好像_
大於零,然後減1,這發生在匹配後的每一行,直到_
達到零。當用n
這類更明智的名稱替換變量_
時,這非常簡單。
一個簡單的演示應該清楚(打印2行遵循匹配foo
任何行):
$ cat file
foo
1
2
3
foo
a
b
c
$ awk 'n && n--;/foo/{n=2}' file
1
2
a
b
所以,當它被匹配與foo
線則經過設置爲2 n
只有真減少n
並打印當前行。由於具有短路評價n
awk
僅減量時n
爲True (N> 0)所以在這種情況下爲n
唯一可能的值是2,1或0
awk有以下結構condition{block}
和當條件評估爲True時,將對當前記錄執行塊。如果您不提供塊awk
使用默認塊{print $0}
所以n && n--;
是沒有塊的條件,只有在正則表達式匹配後對n
行計算爲True。分號只是爲條件n&&n--
劃分條件/foo/
明確表示該條件沒有阻止。
要打印下面的比賽,包括這場比賽,你會做兩行:
$ awk '/foo/{n=3} n && n--' file
foo
1
2
foo
a
b
額外額外:所使用的/usr/xpg4/bin/awk
完整路徑的事實告訴我,這段代碼的目的是爲Solaris機器作爲/usr/bin/awk
是完全破碎,應該不惜一切代價避免。
_
在這裏被用作變量名(有效但顯然令人困惑)。如果你將它改寫爲:
awk 'x && x--; /PATTERN/ { x=2 }' input
然後它更容易解析。每當匹配/PATTERN/
時,變量將被設置爲2
(並且不會輸出該行) - 這是下半部分。第一部分在x
不爲零時觸發,並減少x
以及打印當前行(缺省操作,因爲該子句未指定操作)。
最終結果是在模式匹配後立即打印兩條線,只要這兩條線都不匹配模式。
說明
awk
詞語具有以下形式:
condition action; NEXT_EXPRESSION
如果conditon爲真動作(一個或多個)將被執行。此外請注意,如果條件爲真,但操作已被省略,awk
將執行print
(默認操作)。
你在你的代碼的兩個表達式,將獲得在輸入的每一行執行:
_&&_-- ;
/PATTERN/{_=2}
兩者都是由一個;
分開。正如我告訴,如果省略動作是默認操作print
會發生一樣:
_&&_-- {print};
/PATTERN/ {_=2}
在您的例子_
是一個變量名,它得到由0
輸入的第一行初始化,在第一次使用之前 - 由awk自動執行。
第一個條件是(0) && (0)
..什麼結果是錯誤的,因爲0 && 0
評估爲false
而awk將不會打印。
如果找到該圖案,_
將被設置爲2
這使得第一條件的下一行是(2) && (2)
下一行並(1) && (1)
後的條件已被評估之後線_
遞減。兩者都評估爲true
,awk將打印這些行。
然而,不錯的益智;)
見https://stackoverflow.com/a/17914105/1745001對於在這裏重複了答案。
很好的解釋 – CBR