我在檔案中的兩行內容如下:
#foo:/span>
# bar=<need replacement>/span>
我想在第一行以foo開始,第二行包含bar的情況下,將兩行的#洗掉(取消注釋),并將<>之間的文本替換掉。
我可以用N;P;D回圈使用sed一次完成嗎?或者有什么其他更簡單的方法嗎?
uj5u.com熱心網友回復:
這可能對你有用(GNU sed):
sed -E '/^#?foo/{N;/
.*bar/{s/^#/mg;s/(
.*<).*(>.*)/1replace2/};P;D}'檔案
如果當前行以foo注釋或未注釋開始,那么:
添加以下行
如果下面一行包含
bar這個詞,那么:- 洗掉這兩行中任何一行的前導
#。 - 用
replace替換第二行中<和>之間的任何字符。
- 洗掉這兩行中任何一行的前導
列印/洗掉這兩行中的第一行,然后重復。
N.B. 這允許處理前面的foo,后面是另一個前面的foo,后面是bar。
uj5u.com熱心網友回復:
使用POSIX sed與一個標準N;...;P;D;回圈和基本重碼
(BRE):
sed -e '$! N' -e '/^#(foo:
)#([[:空白:]]*bar)=.*/ s/12=newvalue/' -e P -e D < file
uj5u.com熱心網友回復:
如果你的資料包含多行要匹配的文本,可能需要一個管道化的sed。 例如:
cat input_file
#foo:。
# bar=<need replacement>/span>
#bar:
# foo=<dont replace>
#foo:
# bin=<dont replace>
#foo:
# bar=<need replace>
#foo:
# bash=<dont replace>
第一個sed將處理匹配#foo的條件,如果它存在,那么它將檢查第二個條件,即在下面一行匹配bar。如果這兩個條件都滿足,那么n將從匹配bar的行中替換出#,并且還將把need replacement的內容改為test。
第二個sed管道將使用相同的條件,但我將使用N來檢查和改變下一行,而不是N來檢查下一行的條件,但如果滿足條件則改變第一行并洗掉#
sed -E '/^#foo/ {n;/bar/ s/^#( . *=.).*(.)/1test2/g}' input_file | sed '/^#foo/ {N;/bar/ s/^#//g}'
輸出
foo:
bar=<test>
#bar:。
# foo=<dont replace>/span>
#foo:
# bin=<don't replace>
foo:
bar=<test>
#foo:。
# bash=<dont replace>
uj5u.com熱心網友回復:
這可能是可以做到的,但我會使用一個不同的工具。Awk怎么樣?
awk -v replace="new value" 'm & & /^[^:] :/ { m=0 }
/^#foo:/ { m=1 }
m { sub(/^#/, ""); s(/<[^<>]*>/, replace) }1'/span>
這遵循了我們熟悉的模式,即當我們看到有趣的區域的開始時設定一個狀態變數m,當我們在該區域時執行替換,當我們看到一個新區域的開始時關閉該變數(多少猜測一下這個條件可能是什么樣子的)。
改變這一點并不難,只需在區域開始后尋找固定的行數即可;將狀態變數設定為一個數字,并為每一行減去它。
如果這是一個 Makefile 檔案,使用 make 變數會更優雅和穩健。
ifdef ENABLE
foo:
bar=$(barvalue)
endif
(或者干脆是ifdef barvalue!)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/309918.html
標籤:
