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