2012-06-25 36 views
4

我嘗試用sed在以下文件中插入[塊B]之後的行之後插入線:用sed匹配的文本塊

[Block A] 
line 1 
line 2 

[Block B] 
line 1 
line 2 

[Block C] 
line 1 
line 2 

我使用的命令:

sed '/\[Block B\]/,/^$/a\inserted line' file 

正確的/期望的結果應該是:

[Block B] 
line 1 
line 2 
inserted line 

不過,我得到這個:

[Block B] 
inserted line 
line 1 
inserted line 
line 2 
inserted line 

請告訴我如何使用sed獲得想要的結果。謝謝!

回答

12
sed -e '/\[Block B\]/{:a;n;/^$/!ba;i\inserted line' -e '}' 
+0

非常感謝!這真的很有幫助。但是,我真的不明白爲什麼這個工作大聲笑!我想是時候讀sed – tonytz

+0

你能解釋一下爲什麼你需要額外的-e來使命令工作。以下命令出於某種奇怪原因不起作用: sed -e'/ \ [Block B \]/{:a; n;/^ $ /!ba; i \插入行}'文件 – tonytz

+2

@tonytz您可能會像這些[sed one-liners](http://sed.sourceforge.net/sed1line.txt) – Levon

6

我發現這個問題,同時尋找解決方案,我自己的問題,這是類似的,但有點不同。我在這裏調整了答案來解決我的問題。

我需要在一個塊的配置文件這樣內末尾插入一些文本:

name1 { 
    ... 
} 

name2 { 
    ... 
    inserted text line 1 
    inserted text line 2 
} 

name3 { 
    .... 
} 

爲了實現這一點我把@toyntz評論從上方並且適於它因而:

/^name2 {/,/^}/{ 
    /^}/i\ inserted text line 1 
    /^}/i\ inserted text line 2 
} 

這只是sed表達式;它可以被放置在一個文件,並執行與sed -f這樣的:

$ sed -f sed_expression data_file 

該第一表達式搜索的範圍內開始name2 {線在一行的開頭存在的和與}結束也發生在開始時的一條線。這將選擇要使用的塊。剩餘表達式包含在{花括號}中,並在選定範圍內運行。它包含我們希望插入的每行一條命令,每條命令都有一個表達式/^}/,該表達式與具有閉括號大括號的行相匹配,後跟插入i操作以插入一行文本。 i後面跟着一個\,以便也插入前導空格。

我然後把表達的位進一步,與一個替換兩個插入命令:

/^name2 {/,/^}/{ 
    /^}/i\ 
    inserted text line 1\ 
    inserted text line 2 
} 

這裏通過一個命令插入橫跨以下兩行傳播的文本。請注意第一行上的附加尾部\以繼續執行單個命令。

接下來,我將它縮減爲一行。它使混亂和難以閱讀,但它仍然有效:

/^name2 {/,/^}/{/^}/i\ inserted text line 1\n inserted text line 2 
} 

要插入一個新行\n分開的兩行。聰明的讀者會注意到,實際上有兩行 - 你不能把右括號放在第一行的末尾;這就是爲什麼上面的其他答案有第二個-e表達式。所以,上面是我能做的最好的。爲了表示一個bash命令行:

sed -e '/^name2 {/,/^}/{/^}/i\ inserted text line 1\n inserted text line 2' -e '}' data_file 

我寫了這個手寫的,希望它解釋給任何人看的文本塊的末尾插入怎樣一個sed表達式可以寫入做到這一點。 Sed表達式可能相當隱晦,很難弄清楚 - 希望我的解釋能夠在這方面提供幫助。

0

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

sed '/^\[Block B\]/,/^$/!b;/^$/i\inserted line' file