awk -i inplace '
BEGIN {FS=" "}
BEGINFILE {changed=0}
{ print;if ($1 == "namespace" && !changed) {print "foo";changed=1} }
' *
有沒有更優雅的方式來做到這一點?我錯過了一些內置的構造?我正在運行GNU Awk 4.1.0(我非常喜歡-i就地)。awk每個文件更改一次
awk -i inplace '
BEGIN {FS=" "}
BEGINFILE {changed=0}
{ print;if ($1 == "namespace" && !changed) {print "foo";changed=1} }
' *
有沒有更優雅的方式來做到這一點?我錯過了一些內置的構造?我正在運行GNU Awk 4.1.0(我非常喜歡-i就地)。awk每個文件更改一次
awk -i inplace '$1=="namespace" && !seen[ARGIND]++ {$0=$0 ORS "foo"} 1' *
FS=" "
是默認的,沒有必要明確指定它。
這非常棘手。 ARGIND是文件名ARGV中的索引,因此它對每個文件進行更改,並且我假定一個未初始化的變量是空的,否定它變爲真,ish,遞增和否定將是false-ish,因此每個文件確實觸發一次。 – chx
這不是棘手,只是習慣用法。以這種方式使用一個名爲'seen []'的數組是一種非常常見的AWK習慣用法,它只能在第一次出現任何東西時進行操作。是的,ARGIND是當前正在處理的文件的ARGV數組中的僅有gawk的索引。您可以使用FILENAME,但如果同一個文件在arg列表中多次出現,則會有不同的語義。 'seen [x] ++'是自從'seen [x]'開始爲'zero-or-null'以來第一次被評估爲false',然後後遞增,因此隨後的每一次'seen [x] ++'都是真的。 '!seen [x] ++'是相反的 - 真正的第一次然後是假的。 –
你可以說:
... -F' ' '$1 == "namespace" && !a {$0=$0 RS "foo";a=1}1' file
甚至:
... -F' ' '$1 == "namespace" && !_ {$0=$0 RS "foo";_=1}1' file
如上評論中提及,這是非常類似你寫不同的是它採用了可變RS
什麼插入文本。
爲了給多個文件做到這一點,你需要重新設置變量:
或
... -F' ' 'FNR==1 {a=0} $1 == "namespace" && !a {$0=$0 RS "foo";a=1}1' *
你可以肯定地寫它使其稍短,但我想邏輯會是類似的。 – devnull
我對短版本很好奇。我總是渴望學習:) – chx