$ sed -e 's/.*/ralph said: &/' origmsg.txt
输出如下:
ralph said: Hiya Jim, ralph said: ralph said:
I sure like this sed stuff! ralph said:
该例的替换字符串中使用了 '&' 字符,该字符告诉 sed 插入整个匹配的规则表达式。因此,能够将和 '.*' 匹配的任何内容(行中的零或多个字符的最大组或整行)插入到替换字符串中的任何位置,甚至多次插入。这很好,但 sed 甚至更强大。
那些极好的带反斜杠的圆括号
's///' 命令甚至比 '&' 更好,他允许我们在规则表达式中定义区域,然后能够在替换字符串中引用这些特定区域。作为示例,假设有一个包含以下文本的文档:
foo bar oni eeny meeny miny larry curly moe jimmy the weasel
现在假设要编写一个 sed 脚本,该脚本将把 "eeny meeny miny" 替换成 "Victor eeny-meeny Von miny" 等等。要这样做,首先要编写一个由空格分隔并和三个字符串匹配的规则表达式。
'.* .* .*'
现在,将在其中每个感兴趣的区域两边插入带反斜杠的圆括号来定义区域:
'(.*) (.*) (.*)'
除了要定义三个可在替换字符串中引用的逻辑区域以外,该规则表达式的工作原理将和第一个规则表达式相同。下面是最终脚本:
$ sed -e 's/(.*) (.*) (.*)/Victor 1-2 Von 3/' myfile.txt
如您所见,通过输入 'x'(其中,x 是从 1 开始的区域号)来引用每个由圆括号定界的区域。输入如下:
Victor foo-bar Von oni Victor eeny-meeny Von miny Victor larry-curly Von moe Victor jimmy-the Von weasel
随着对 sed 越来越熟悉,您能够花最小力气来进行相当强大的文本处理。您可能想如何使用熟悉的脚本语言来处理这种问题 -- 能用一行代码轻易实现这样的解决方案吗?
组合使用
在开始创建更复杂的 sed 脚本时,需要有输入多个命令的能力。有几种方法这样做。首先,能够在命令之间使用分号。例如,以下命令系列使用 '=' 命令和 'p' 命令,'=' 命令告诉 sed 打印行号,'p' 命令明确告诉 sed 打印该行(因为处于 '-n' 模式)。
$ sed -n -e '=;p' myfile.txt
无论什么时候指定了两个或更多命令,都按顺序将每个命令应用到文档的每一行。在上例中,首先将 '=' 命令应用到第 1 行,然后应用 'p' 命令。接着,sed 继续处理第 2 行,并重复该过程。虽然分号很方便,但是在某些场合下,他不能正常工作。另一种替换方法是使用两个 -e 选项来指定两个不同的命令:
$ sed -n -e '=' -e 'p' myfile.txt
然而,在使用更为复杂的附加和插入命令时,甚至多个 '-e' 选项也不能帮我们的忙。对于复杂的多行脚本,最好的方法是将命令放入一个单独的文档中。然后,用 -f 选项引用该脚本文档:
$ sed -n -f mycommands.sed myfile.txt
这种方法虽然可能不太方便,但总是管用。
一个地址的多个命令
有时,可能要指定应用到一个地址的多个命令。这在执行许多 's///' 以变换源文档中的字和语法时特别方便。要对一个地址执行多个命令,可在文档中输入 sed 命令,然后使用 '{ }' 字符将这些命令分组,如下所示:
1,20{ s/[Ll]inux/GNU/Linux/g s/samba/Samba/g s/posix/POSIX/g } 上例将把三个替换命令应用到第 1 行到第 20 行(包括这两行)。还能够使用规则表达式地址或二者的组合:
1,/^END/{ s/[Ll]inux/GNU/Linux/g s/samba/Samba/g s/posix/POSIX/g p } 该例将把 '{ }' 之间的任何命令应用到从第 1 行开始,到以字母 "END" 开始的行结束(假如在源文档中没发现 "END",则到文档结束)的任何行。
附加、插入和更改行
既然在单独的文档中编写 sed 脚本,我们能够利用附加、插入和更改行命令。这些命令将在当前行之后插入一行,在当前行之前插入一行,或替换模式空间中的当前行。他们也能够用来将多行插入到输出。插入行命令用法如下:
i This line will be inserted before each line
假如不为该命令指定地址,那么他将应用到每一行,并产生如下的输出:
This line will be inserted before each line line 1 here
This line will be inserted before each line line 2 here
This line will be inserted before each line line 3 here
This line will be inserted before each line line 4 here
假如要在当前行之前插入多行,能够通过在前一行之后附加一个反斜杠来添加附加行,如下所示:
i insert this line and this one and this one and, uh, this one too.
附加命令的用法和之类似,但是他将把一行或多行插入到模式空间中的当前行之后。其用法如下:
a insert this line after each line. Thanks! :)
另一方面,“更改行”命令将实际替换模式空间中的当前行,其用法如下:
c You're history, original line! Muhahaha!
因为附加、插入和更改行命令需要在多行输入,所以将把他们输入到一个文本 sed 脚本中,然后通过使用 '-f' 选项告诉 sed 执行他们。使用其他方法将命令传递给 sed 会出现问题。
下一篇
在下一篇、也是本 sed 系列的最后一篇文章中,我将为您演示许多使用 sed 来完成不同类型任务的极佳实例。我将不但为您显示脚本做些什么,还显示为什么那样做。完成之后,您将掌控更多有关如何在不同项目中使用 sed 的极佳知识。到时候见!
参考资料
- 阅读 developerWorks 上 Daniel 的其他 sed 文章:通用线程:sed 实例,第 1 部分和第 3 部分。
- 查看 Eric Pement 极佳的 sed faq。
- 能够在 ftp.gnu.org 找到 sed 3.02 资源。
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




