Stream 编辑器 - 循环
与其他编程语言一样,SED 也提供循环和分支工具来控制执行流程。 在本章中,我们将进一步探讨如何在 SED 中使用循环和分支。
SED 中的循环类似于 goto 语句。 SED 可以跳转到标签标记的行并继续执行剩余的命令。 在 SED 中,我们可以定义一个 label 如下:
:label :start :end :up
在上面的例子中,冒号(:)后面的名字暗示了标签的名字。
要跳转到特定标签,我们可以使用 b 命令后跟标签名称。 如果省略标签名称,则 SED 跳转到 SED 文件的末尾。
让我们编写一个简单的 SED 脚本来理解循环和分支。 在我们的 books.txt 文件中,有几个书名及其作者条目。 以下示例将书名及其作者姓名组合在一行中,用逗号分隔。 然后它搜索模式"Paulo"。 如果模式匹配,它会在该行的前面打印一个连字符 (-),否则它会跳转到打印该行的 Print 标签。
[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
乍一看,上面的脚本可能看起来很神秘。 让我们揭开这个神秘面纱。
前两个命令是不言自明的 h;n;H;x 和 s/\n/, / 结合书名和作者,用 a 分隔 逗号 (,)。
第三个命令仅在模式不匹配时才跳转到标签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