2013-02-01 59 views
4

我試圖使用sed從文件中刪除塊代碼。要刪除的塊在文件中出現多次,並且還跨越多行。此外,該塊中有不同的內容,但有明確的開始和結束的描述。使用sed來查找並替換多行代碼

我已經嘗試了很多方法來獲得這個工作,並且遇到了懶惰在sed中工作的問題,並跨線匹配。

這裏是什麼,我試圖做一個例子:

good stuff a 
good stuff same line START 
bad stuff 1.0 
bad stuff 1.1 
END 
good stuff b 
good stuff b 
good stuff same line START bad stuff 2.0 
bad stuff 2.0 
END 
good stuff c 

變爲:

good stuff a 
good stuff same line 
good stuff b 
good stuff b 
good stuff same line 
good stuff c 

這裏有一些方法,到目前爲止我都試過了。

sed -n '1h;1!H;${;g;s/START.*END//mg;p;}' <test> test2獲得跨線工作。

sed -n 's/START[^END]*END//g' <test> test2只有否定E或N或D.

sed -n 's/START.*?END//g' <test> test2不懶惰行爲。

謝謝。

+0

什麼是「懶惰」? –

回答

1

一個sed可能很難做到這一點。兩個sed那麼,我們就簡單了:

sed 's/START/\nSTART\n/g' | sed '/START/,/END/d'

+0

這似乎並沒有在我的終端中添加換行符 –

+0

它完全按照您在問題中提出的要求工作。目標不是添加換行符,而是將START移動到一個單獨的行,然後通過範圍刪除將其刪除。 – aragaer

+0

適用於我的Linux機器,但不適用於Mac。謝謝! –

1

如何:

$ sed '/START/,/END/d' file.txt 
good stuff a 
good stuff b 
good stuff b 
good stuff c 

瞭解更多關於rangeshere

+0

將無法​​正常工作,因爲START可能與好東西在同一行 – aragaer

+0

正確,但是再次,您不應該使用sed解析html ... –

2

的sed就不大適合處理多行輸入。 改用awk。
你想匹配它的正則表達式的一行,並關閉打印,如果它是'壞'塊的開始。以下是您的文件示例:

$ awk ' 
BEGIN { pr = 1; } 
/^START/ { pr = 0; } 
      { if (pr) print; } 
/^END/ { pr = 1; } 
' < yourfile 
good stuff a 
good stuff b 
good stuff b 
good stuff c 
+0

這會嚼碎整條線,因而不符合題。 – Josh

1

這可能會爲你工作(GNU SED):

sed '/START/!b;:a;/END/bb;$!{N;ba};:b;s/START.*END//' file 
+0

在一行中放置START和END以及多次發生時處理得很好。 – Josh

0

sed的是簡單的換人在一行上一個極好的工具,爲別的用途awk:

$ awk 'sub(/START.*|.*END/,""){f=!f;if(NF)print;next} !f' file 
good stuff a 
good stuff same line 
good stuff b 
good stuff b 
good stuff same line 
good stuff c 
+0

解決這個問題,但不使用sed,不適用於某些邊緣情況(請參閱potong的解決方案)。 – Josh

+0

顯然它不使用sed,因爲這不適合sed。你指的是哪種邊緣情況? –