linux实用工具之sed实例

来源:互联网 发布:黑魂3最美捏脸数据 编辑:程序博客网 时间:2024/04/30 09:06

sed是linux上进行文本过滤和转换的流编辑器工具。sed以行为处理单位,依次从输入文件(可以是stdin,pipeline或者文件)读取每一行,执行相应的脚本,然后把处理过后的结果输出(同样可以输出到stdout,pipeline或者文件)。sed把当前处理的行存储在临时缓冲区中,称为模式空间(pattern space)。一旦sed完成对模式空间中行的处理,模式空间中的行就被输出。行被处理完成之后,就被移出模式空间,程序接着读入下一行,处理,输出,移出……文件输入的最后一行被处理完以后sed结束。通过存储每一行在临时缓冲区,然后在缓冲区中操作该行,保证了原始文件不会被破坏。

下面通过一个典型的例子来说明sed的使用方法,

nl /etc/passwd | sed ‘2,5d’

这个sed命令从pipeline读取输入,然后执行脚本’2,5d’,输出到stdout。这个脚本的作用是删除第2行到第5行,其余的行输出到stdout。这里引出两个概念,AddressCommand

rex@rex-VirtualBox:~$ nl /etc/passwd | sed '2,5d'     1  root:x:0:0:root:/root:/bin/bash     6  games:x:5:60:games:/usr/games:/bin/sh     7  man:x:6:12:man:/var/cache/man:/bin/sh     8  lp:x:7:7:lp:/var/spool/lpd:/bin/sh     9  mail:x:8:8:mail:/var/mail:/bin/sh    10  news:x:9:9:news:/var/spool/news:/bin/sh

sed 中的Address是用来定位要处理的文本行的位置。指定一个Address就是只处理匹配的文本行,如sed ‘2d’就是删除第二行。
指定2个Address就是处理指定范围内的行。当不指定Address时,默认处理所有的输入行。

rex@rex-VirtualBox:~$ nl /etc/passwd | sed '2d'     1  root:x:0:0:root:/root:/bin/bash     3  bin:x:2:2:bin:/bin:/bin/sh     4  sys:x:3:3:sys:/dev:/bin/sh     5  sync:x:4:65534:sync:/bin:/bin/sync     6  games:x:5:60:games:/usr/games:/bin/sh     7  man:x:6:12:man:/var/cache/man:/bin/sh     8  lp:x:7:7:lp:/var/spool/lpd:/bin/sh     9  mail:x:8:8:mail:/var/mail:/bin/sh    10  news:x:9:9:news:/var/spool/news:/bin/sh

sed 中的Command描述了要对文本行执行什么动作。这里有个表格总结的蛮好,原文在这里。

这里写图片描述

当然关于Address和Command最权威的解释还是man sed了。

  1. 打印出包含匹配内容的行,因为默认模式空间都输出到stdout的,所以第一行输出了2次

    rex@rex-VirtualBox:~$ nl /etc/passwd | sed  '/root/p'  1  root:x:0:0:root:/root:/bin/bash 1  root:x:0:0:root:/root:/bin/bash 2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh 3  bin:x:2:2:bin:/bin:/bin/sh 4  sys:x:3:3:sys:/dev:/bin/sh 5  sync:x:4:65534:sync:/bin:/bin/sync 6  games:x:5:60:games:/usr/games:/bin/sh 7  man:x:6:12:man:/var/cache/man:/bin/sh 8  lp:x:7:7:lp:/var/spool/lpd:/bin/sh 9  mail:x:8:8:mail:/var/mail:/bin/sh10  news:x:9:9:news:/var/spool/news:/bin/sh
  2. 给sed增加-n选项,不输出模式空间,只打印包含匹配内容的行

    rex@rex-VirtualBox:~$ nl /etc/passwd | sed -n '/root/p'  1  root:x:0:0:root:/root:/bin/bash
  3. 删除第2行,这里只指定了一个Address

    rex@rex-VirtualBox:~$ nl /etc/passwd | sed '2d' 1  root:x:0:0:root:/root:/bin/bash 3  bin:x:2:2:bin:/bin:/bin/sh 4  sys:x:3:3:sys:/dev:/bin/sh 5  sync:x:4:65534:sync:/bin:/bin/sync 6  games:x:5:60:games:/usr/games:/bin/sh 7  man:x:6:12:man:/var/cache/man:/bin/sh 8  lp:x:7:7:lp:/var/spool/lpd:/bin/sh 9  mail:x:8:8:mail:/var/mail:/bin/sh10  news:x:9:9:news:/var/spool/news:/bin/sh
  4. 删除第2行到第5行

    rex@rex-VirtualBox:~$ nl /etc/passwd | sed '2,5d' 1  root:x:0:0:root:/root:/bin/bash 6  games:x:5:60:games:/usr/games:/bin/sh 7  man:x:6:12:man:/var/cache/man:/bin/sh 8  lp:x:7:7:lp:/var/spool/lpd:/bin/sh 9  mail:x:8:8:mail:/var/mail:/bin/sh10  news:x:9:9:news:/var/spool/news:/bin/sh
  5. 删除第3行到最后一行, $在正则表达式中表示最后一行

    rex@rex-VirtualBox:~$ nl /etc/passwd | sed '3,$d' 1  root:x:0:0:root:/root:/bin/bash 2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh
  6. 替换root为root2,试图用模式root去匹配模式空间,匹配成功的话,使用root2替换root。

    rex@rex-VirtualBox:~$ nl /etc/passwd |sed 's/root/root2/'  1  root2:x:0:0:root:/root:/bin/bash 2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh 3  bin:x:2:2:bin:/bin:/bin/sh 4  sys:x:3:3:sys:/dev:/bin/sh 5  sync:x:4:65534:sync:/bin:/bin/sync 6  games:x:5:60:games:/usr/games:/bin/sh 7  man:x:6:12:man:/var/cache/man:/bin/sh 8  lp:x:7:7:lp:/var/spool/lpd:/bin/sh 9  mail:x:8:8:mail:/var/mail:/bin/sh10  news:x:9:9:news:/var/spool/news:/bin/sh
  7. 题6只对模式空间的第一个root执行了替换,增加g命令,作用到整个模式空间

    rex@rex-VirtualBox:~$ nl /etc/passwd |sed 's/root/root2/g'  1  root2:x:0:0:root2:/root2:/bin/bash 2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh 3  bin:x:2:2:bin:/bin:/bin/sh 4  sys:x:3:3:sys:/dev:/bin/sh 5  sync:x:4:65534:sync:/bin:/bin/sync 6  games:x:5:60:games:/usr/games:/bin/sh 7  man:x:6:12:man:/var/cache/man:/bin/sh 8  lp:x:7:7:lp:/var/spool/lpd:/bin/sh 9  mail:x:8:8:mail:/var/mail:/bin/sh10  news:x:9:9:news:/var/spool/news:/bin/sh
  8. 只打印发生了替换操作的行

    rex@rex-VirtualBox:~$ nl /etc/passwd |sed  -n 's/root/root2/gp'  1  root2:x:0:0:root2:/root2:/bin/bash
  9. 替换以root作为行开头的单词,^表示行起始位置,$表示行结束位置。关于正则表达式可参考正则表达式总结

    rex@rex-VirtualBox:~$ cat /etc/passwd |sed -n 's/^root/root2/gp' root2:x:0:0:root:/root:/bin/bash
  10. 截取本机eth0接口的ip地址

    未截取时长这样:

    rex@rex-VirtualBox:~$ ifconfig eth0|grep "inet addr"      inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0

    截取后长这样:

    rex@rex-VirtualBox:~$ ifconfig eth0 | grep "inet addr" | sed 's/^.*addr://g' | sed 's/\s*Bcast:.*$//g'10.0.2.15

    sed太强大了,这里解释下,第一个sed命令删除了ip地址前的部分,即行开头到”addr:”的部分。第二个sed命令删除了ip地址后的部分,即ip地址后面的空格到行尾的部分。”\s”匹配任何空白字符,包括space, tab, form feed,等价于”[ \f\n\r\t\v]”。

  11. 在第一行的前面一行插入一行文本

    rex@rex-VirtualBox:~$ nl /etc/passwd |sed '1i beginning of password'beginning of password 1  root:x:0:0:root:/root:/bin/bash 2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh 3  bin:x:2:2:bin:/bin:/bin/sh 4  sys:x:3:3:sys:/dev:/bin/sh 5  sync:x:4:65534:sync:/bin:/bin/sync 6  games:x:5:60:games:/usr/games:/bin/sh 7  man:x:6:12:man:/var/cache/man:/bin/sh 8  lp:x:7:7:lp:/var/spool/lpd:/bin/sh 9  mail:x:8:8:mail:/var/mail:/bin/sh10  news:x:9:9:news:/var/spool/news:/bin/sh
  12. 在第10行的后面一行插入一行

rex@rex-VirtualBox:~$ nl /etc/passwd  |sed '10a endding of password'     1  root:x:0:0:root:/root:/bin/bash     2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh     3  bin:x:2:2:bin:/bin:/bin/sh     4  sys:x:3:3:sys:/dev:/bin/sh     5  sync:x:4:65534:sync:/bin:/bin/sync     6  games:x:5:60:games:/usr/games:/bin/sh     7  man:x:6:12:man:/var/cache/man:/bin/sh     8  lp:x:7:7:lp:/var/spool/lpd:/bin/sh     9  mail:x:8:8:mail:/var/mail:/bin/sh    10  news:x:9:9:news:/var/spool/news:/bin/shendding of password
    13.

http://www.cnblogs.com/stephen-liu74/archive/2011/11/17/2245130.html
https://www.cnblogs.com/ggjucheng/archive/2013/01/13/2856901.html