Linux命令五分钟

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

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

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

===

[正文开始]

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

例十 如果设定了很多-e的command,它们的执行顺序是怎样的呢?

[rocrocket@rocrocket programming]$ cat mysed.txt
Beijing 2003
Beijing 2004
Beijing 2005
Beijing 2006Beijing 2007
Beijing 2008
[rocrocket@rocrocket programming]$ sed -e ‘s/Beijing/London/g’ -e ‘/Beijing/d’ mysed.txt
London 2003
London 2004
London 2005
London 2006
London 2007
London 2008

后一个-e中包含了删除Beijing所在行,但是最后的结果却是所有行都输出了,其实这就是由执行顺序导致的,第一个-e已经将Beijing都替换成了London了,所以怪不得第二个-e找不到Beijing了。

例十一 读取一个特定文件的内容,将其插入到本文件指定的地方:

[rocrocket@rocrocket programming]$ cat ins.txt
====China====
[rocrocket@rocrocket programming]$ cat mysed.txt
Beijing 2003
Beijing 2004
Beijing 2005
Beijing 2006
Beijing 2007
Beijing 2008
[rocrocket@rocrocket programming]$ sed ‘/2005/r ins.txt’ mysed.txt
Beijing 2003
Beijing 2004
Beijing 2005
====China====
Beijing 2006
Beijing 2007
Beijing 2008

此命令用于在含有2005的行下面插入ins.txt文件的内容。

例十二 将某些指定行写入到特定文件中

[rocrocket@rocrocket programming]$ sed ‘/200[4-6]/w new.txt’ mysed.txt
Beijing 2003
Beijing 2004
Beijing 2005
Beijing 2006
Beijing 2007
Beijing 2008
[rocrocket@rocrocket programming]$ cat new.txt
Beijing 2004
Beijing 2005
Beijing 2006

看,w new.txt表示将含有2004、2005、2006的行写入到new.txt文件中。

例十三 使用a\在特定行“下面”插入特定内容

[rocrocket@rocrocket programming]$ cat new.txt
Beijing 2004
Beijing 2005
Beijing 2006
[rocrocket@rocrocket programming]$ sed ‘/2004/a\China’ mysed.txt
Beijing 2003
Beijing 2004
China
Beijing 2005
Beijing 2006
Beijing 2007
Beijing 2008

使用a\然后加上需要加的内容即可。

例十四 使用i\在特定行“上面”插入特定内容

[rocrocket@rocrocket programming]$ sed ‘/2004/i\China’ mysed.txt
Beijing 2003
China
Beijing 2004
Beijing 2005
Beijing 2006
Beijing 2007
Beijing 2008

例十五 替换特定字符

[rocrocket@rocrocket programming]$ cat mysed.txt
Beijing 2003
Beijing 2004
Beijing 2005
Beijing 2006
Beijing 2007
Beijing 2008
[rocrocket@rocrocket programming]$ sed ‘y/eijng/EIJNG/’ mysed.txt
BEIJING 2003
BEIJING 2004
BEIJING 2005
BEIJING 2006
BEIJING 2007
BEIJING 2008

使用了y就表示将第一栏的每个字符都替换为相对应的第二栏的字符。

例十六 对匹配行的下一行进行处理

[rocrocket@rocrocket programming]$ cat mysed.txt
Beijing 2003
Beijing 2004
Beijing 2005
Beijing 2006
Beijing 2007
Beijing 2008
[rocrocket@rocrocket programming]$ sed ‘/2004/{n;y/eijng/EIJNG/;}’ mysed.txt
Beijing 2003
Beijing 2004
BEIJING 2005
Beijing 2006
Beijing 2007
Beijing 2008

这个例子就是找含有2004的行,然后将它下面的一行中的eijng替换为大写的EIJNG。这里面的“n;”起到了“移至下一行”的作用。n背后的含义其实是将下一行放到模式空间中去。

[rocrocket@rocrocket programming]$ cat mysed.txt
Beijing 2003
Beijing 2004
Beijing 2005
Beijing 2006
Beijing 2007
Beijing 2008
[rocrocket@rocrocket programming]$ sed ‘/200/{n;y/eijng/EIJNG/;}’ mysed.txt
Beijing 2003
BEIJING 2004
Beijing 2005
BEIJING 2006
Beijing 2007
BEIJING 2008

这个例子更加典型,你可以发现,BEIJING是隔行出现的。你知道为什么么?不说答案了,相信你能自己思考出来!

ps:sed的流艺术系列到这里就结束了:)

ps:其实sed的学问还很大,正则表达式也有很多需要学习的地方,我也在学习中…这个小系列,就当抛砖引玉了,希望对你有用!

over~

8条评论

  1. Bravo!
    感谢博主的精彩文章。最近半个月,每天起来的第一件事就是看几篇博主的博文!
    这个sed系列对我的帮助很大,不过这篇里有一些小细节,也许值得注意:
    1.在例十中,Beijing 2006Beijing 2007出现在同一行,而我用同样的命令处理,结果替换出来的London2006London2007也在同一行,意思博主笔误。
    2.在举例y的作用时,我觉得没有很好的区分开y/../../和s/../../的区别。不如用y/ei/EI/和s/ei/EI为例,可以很好的区别开两个命令。

  2. 您好,请教一个问题。
    问题如下: /etc下有且只有2个重复小写字母(比如aa,bb等)的文件目录有哪些?
    我考虑一下,用grep命令可以这么写: ls /etc |grep -E ‘([a-z])\1’.
    然后我就有两个问题:
    1.用sed命令怎么写?ls /etc |sed -E ‘([a-z])\1’行不通,不知为何?
    2.ls /etc |grep -E ‘([a-z])\1’ 所匹配的还有3个重复字符的(比如ppp),如何保证匹配有且只有2个?
    我试验了一下一个解法但是有问题: ls /etc |grep -E ‘([a-z])\1[^\1]’发现根本没有对^\1进行处理,不知为何?

    我是一个写脚本的新手,好多地方掌握不精确,给您添麻烦了,望百忙之中赐教。

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

发表您的评论

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