2013-01-09 39 views
4

我張貼this question以及與此需要幫助,在sed

sed '/^void.*{$/!b;:a;/\n}$/bb;$!{N;ba};:b;s/\n/&test1&/;s/\(.*\n\)\(.*\n\)/\1test2\n\2/' file

有人回答我新的sed和正則表達式,我不能夠理解的是各部分的功能理解這個正則表達式。

我會盡力解釋我所瞭解的事情,並且你們可以填補缺失的東西。我將通過字符會由字符

  1. ^void.*{$ - 這意味着任何與void開始,以{
  2. /!b;結束我沒有得到這是什麼一樣。現在b用於branching。什麼是/在那裏做
  3. :a;是製作標籤a
  4. /\n同樣沒有明白/
  5. }$}
  6. /bb結束我不明白,如果不結束它
  7. $!指的文件
  8. {N;沒有得到它的意思,N意味着複製緩衝區中的下一行但得到了{
  9. :b沒有明白。 b爲分支,但不知道它在那裏做我認爲它替換\ n,其中\ntest1\n但不知道
  10. s/\(.*\n\)\(.*\n\)/\1test2\n\2/不明白這其中還有
+0

看起來像回答你的問題的人添加了[解釋](http://stackoverflow.com/a/14215634/1938444)。 – mgamba

+0

他在小組中加入了外國語,我甚至都不明白。我想逐字理解字符 – user175386049

+0

sed是一個很好的工具,可以簡單地替換一行代碼,但是對於其他任何你應該使用awk代替的東西。我一直在使用sed 30年,甚至無法猜測你發佈的命令是在做什麼。如果你發現自己使用的不僅僅是「s」和「g」sed命令,你可能使用了錯誤的工具,所以不要浪費你的時間在這些東西上,只需要一個awk解決方案,它會更清晰,更簡單,未來更容易提升。 –

回答

2

您可以用;字符鏈的多個sed的表情在一起。這裏分別看一下每一個。

第一個表達式/^void.*{$/!b在劃分/之間有一個匹配表達式。它匹配:

^ - 行

void的開始 - 隨後的字符 「空缺」

.* - 其次是任何

{ - 接着是左花

$ - 後面跟着行尾

第一個表達式中的修飾符!b表示如果匹配器不匹配,則中止sed評估。

:a表達式是一個標籤。它與goto-like sed特性一起使用,稱爲分支。我們將在下一個表達式中看到如何使用標籤。

表達/\n}$/bb匹配:

\n - 換行符

} - 後跟一個右捲曲

$ - 隨後的線的端部

修飾語bb意味着如果你找到一個匹配的話,可以在標籤b中選擇「分支」。標籤b在後面的表達式中定義爲:b

$!{N;ba}表達式應該被視爲一個,儘管它的中間有一個;。在這種情況下,curlies代表了一系列旨在一起執行的命令。

$! - 如果它不是輸入

{的結束 - 開始命令的組(在這種情況下,存在其中兩個)

N - 讀取另一行,默默

ba - 分支標籤

} - 結束命令組

接下來是標籤:b,當我們通過/\n}$/bb表達式自己匹配單個線條上的單個}時,我們會打出標籤。

最後有兩種替代模式,這是非常標準的正則表達式。表達前的s實質上是指s/find_this/replace_it_with_this/。在s/\n/&test1&/的情況下,我們有:

\n - 找到一個換行符

/ - 與

&代替它 - 這是在第一個表達式(匹配在這種情況下的東西,換行)

test1 - test1的

&字 - 又一次的東西被匹配

所以基本上s/\n/&test1&/意味着用\ntest1\n代替下一個\n

最後一個表達式類似,但引入了一些稱爲捕獲的東西。捕獲讓你仍然可以匹配所有內容,但保留\(\)之間的所有內容以用於替換表達式部分。例如,如果給定輸入字符串abcde,則s/a\(b\)c\(d\)e/\1 \2/將輸出b d。在該示例中,\1\2分別被替換爲在轉義對象bd中捕獲的內容。

s - 這是一個替代模式:

/ - 找到

\( - 並投入\1更換可變

. - 任何

* - 和它的任何量

\n - 包括你遇到

\)第一個換行符 - (對於\1拍攝結束)

\( - 並投入\2更換可變

. - 任何

* - 和它的任何數量

\n - 包括你遇到

\)第一個換行符 - (捕捉的末尾\2

/ - 與

\1取代這一切 - 第一件事捕獲,

test2\n - test2 \ n,

\2 - 並捕獲第二件事。

+0

謝謝老兄你的搖滾,你真的清除了我懷疑的疑惑 – user175386049

2

術語:

/^void.*{$/!b 

表示匹配^void.*{$並且斜線是圍繞正則表達式的正則表達式分隔符。所以你得到/^void.*{$/。如果感嘆號符合/regex/!中的匹配表達式,那麼這意味着如果正則表達式匹配not,則執行以下命令。以下命令是b這是分支。其中沒有標籤名稱,在腳本的末尾分支。因此,總體而言,該表達式嘗試匹配^void.*{$(即,以void開始並以{結尾的行)並在匹配失敗(!)的情況下跳過腳本的其餘部分(b)。

這件事:

:a;/\n}$/bb;$!{N;ba}; 

開始標籤:a;和嘗試匹配\n}$(換行和線路上的單})這又是封閉在/regex/。一旦匹配,它將分支(b)標記爲b(因此,/regex/bb)。如果這不是輸入的結尾($!),則讀取一行N並跳回到標籤a(ba)。這裏的捲曲對(即,{commands})創建一個塊。該塊 作爲一個整體執行,如果$!爲真,這意味着有更多的輸入。所以$!{N;ba}僅僅意味着:

If not end of input: 
begin 
    real line 
    jump to label a 
end 
+0

感謝哥們,我現在越來越多 – user175386049