Linux命令五分钟

回答一位朋友关于“复杂sed命令”的问题

本原创文章属于《Linux大棚》博客,博客地址为http://roclinux.cn。文章作者为rocrocket。

为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅。

===

[正文开始]

首先谢谢rocyu朋友对我博客的关注。

rocyu的问题:

博主,我有一个问题想请教您。您能帮我详细解释一下这个命令吗:
sed -e ’s/72;/72,next_val=0×11111111;/;/@/{h;s/test/next/g;x;G}’ fmt_vuln.c

rocrocket的回答

这个命令的意思是:

查看fmt_vuln.c文件,其中每行中第一个包含72;的地方都替换为72,next_val=0x11111111;,然后查看本行中是否有@符号,如果有,则将本行内容存入“保持空间”中,然后在模式空间的内容中,将test都替换为next,然后再交换模式空间和保持空间,最后将保持空间中的内容追加到模式空间内容的尾部(这样就实现了增加一行的目的)。

这个过程描述可能有点晦涩,如果你对模式空间、保持空间、h命令、x动作、G动作以及替换命令都非常熟悉的话,理解这条命令应该比较容易。

建议从头到尾看看:

《sed的流艺术之一》-linux命令五分钟系列之二十一

《sed的流艺术之二》-linux命令五分钟系列之二十二

《sed的流艺术之三》-linux命令五分钟系列之二十三

《sed的流艺术之四》-linux命令五分钟系列之二十四

=================================================================

链接知识:

1 构成复杂sed处理过程的方法:

引用http://serverbbs.ccw.com.cn/redirect.php?tid=17961&goto=lastpost网址的描述(谢谢这篇帖子的作者)。

在开始创建更复杂的 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

这种方法虽然可能不太方便,但总是管用。

2 h、x和G

在sed里,h表示将模式空间中的内容拷贝到”保持空间(hold space)”中。“保持空间”是sed中除了模式空间外的另一个暂存数据的地方。

x表示交换模式空间和保持空间中的内容。

G表示将保持空间的内容追加到模式空间中内容的尾部。

3 s///g和s///

这两个都是sed里的替换命令,两者的唯一区别在于g。

g表示全局的意思,即global,也就是说如果一行里出现两次匹配串,那么所有的匹配串都会被替换。

如果不带g,则只会替换每一行里第一个匹配串。

over~

2条评论

发表您的评论

请您放心,您的信息会被严格保密。必填项已标识 *