Sed迴圈


像其他的程式設計語言,sed還提供了一個迴圈和分支工具來控制程式的執行流程。本教學將探討如何使用sed的迴圈和分支。

sed迴圈的工作原理類似於現代程式設計語言中的goto語句。 sed可以跳轉到標記標籤的行並繼續執行下面提供該標籤的剩餘命令。

以下是對在sed定義一個標籤的語法。在這裡,冒號後的名稱(:)暗示的標籤名稱。

:label 
:start 
:end 
:up

要跳轉到一個特定的標籤,我們可以使用 b 命令後面跟標籤名稱。如果標籤的名稱省略,則 sed 跳轉到 sed 檔案的末尾。

考慮一下我們有一個待處理文字檔案books.txt ,它有以下內容:

A Storm of Swords
George R. R. Martin
The Two Towers
J. R. R. Tolkien
The Alchemist
Paulo Coelho
The Fellowship of the Ring
J. R. R. Tolkien
The Pilgrimage
Paulo Coelho
A Game of Thrones
George R. R. Martin

下面的例子是連線書名,並在一行用逗號分隔作者姓名。然後,它會搜尋模式“Paulo”。如果能夠匹配,它列印一個連字元(- )在該行的前面,否則跳轉到列印行列印標籤。

[jerry]$ sed -n ' 
h;n;H;x 
s/\n/, / 
/Paulo/!b Print 
s/^/- / 
:Print 
p' books.txt

執行上面的程式碼,會得到如下結果:

A Storm of Swords, George R. R. Martin 
The Two Towers, J. R. R. Tolkien 
- The Alchemist, Paulo Coelho 
The Fellowship of the Ring, J. R. R. Tolkien 
- The Pilgrimage, Paulo Coelho
A Game of Thrones, George R. R. Martin 

初看起來,上面的指令碼可能看起來神秘。讓我們看看這是什麼情況。

  • 最初sed讀入模式緩衝區第一行即書名和保持緩衝區保持為空。後執行-h命令模式緩衝區被複製到保留緩衝區。現在,這兩個緩衝區包含了本書即標題. A Storm of Swords. 接下來n命令列印當前的模式緩衝區(在本例中沒有列印出來,因為-n選項),清除當前圖形緩衝區讀取輸入的下一行。現在模式緩衝區包含George R. R. Martin。

  • 第三個命令跳到僅當模式不匹配,否則取代是由第四指令執行的標籤Print。

  • :Print 僅僅是一個標簽名,p是列印命令。

為了提高可讀性,每個sed命令被放置在一個單獨的行。然而,人們可以選擇將所有命令在一行中,如下所示:

[jerry]$ sed -n 'h;n;H;x;s/\n/, /;/Paulo/!b Print; s/^/- /; :Print;p' books.txt 

執行上面的程式碼,會得到如下結果:

A Storm of Swords, George R. R. Martin 
The Two Towers, J. R. R. Tolkien 
- The Alchemist, Paulo Coelho 
The Fellowship of the Ring, J. R. R. Tolkien 
- The Pilgrimage, Paulo Coelho 
A Game of Thrones, George R. R. Martin