sed [-nefr] [动作]

功能

sed 可以分析处理标准输入的数据, 然后将它们输出到标准输出。可进行的处理包括取代、删除、新增、撷取特定行等等。

举例

例1:将 /etc/passwd 的内容列出,并且需要打印行号,同时,将第 3~28 行删除

$nl /etc/passwd |sed '3,28d'

输入之后,产生如下输出:

1  root:x:0:0:root:/root:/bin/bash
2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh
29  polkituser:x:107:115:PolicyKit,,,:/var/run/PolicyKit:/bin/false
30  haldaemon:x:108:116:Hardware abstraction layer,,,:/var/run/hald:/bin/false
31  gdm:x:109:117:Gnome Display Manager:/var/lib/gdm:/bin/false

注意:

  • 原本应该是sed -e 才对,这里没-e 也行。
  • sed 后面接的动作,必须用 '' 两个单引号括住。

例2:将 /etc/passwd 的内容列出,并且需要打印行号,同时,将第 3 行删除

$nl /etc/passwd | sed '3d'

输出将不显示第3行由于篇幅,就省略了。

例3 :将 /etc/passwd 的内容列出,并且需要打印行号,同时,将第3行到最后一行删除

$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

例4:在例1的基础上,在第2行后(亦即是加在第3行)加上 drink tea? 字样

$nl /etc/passwd |sed '3,28d'|sed '2a drink tea'

输入之后,输出如下:

     1  root:x:0:0:root:/root:/bin/bash
     2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh
drink tea
    29  polkituser:x:107:115:PolicyKit,,,:/var/run/PolicyKit:/bin/false
    30  haldaemon:x:108:116:Hardware abstraction layer,,,:/var/run/hald:/bin/false
    31  gdm:x:109:117:Gnome Display Manager:/var/lib/gdm:/bin/false

例5: 在例1的基础上,在第2行前(亦即是加在第2行)加上 drink tea? 字样

$nl /etc/passwd |sed '3,28d'|sed '2i drink tea'

输入之后,输出如下:

     1  root:x:0:0:root:/root:/bin/bash
drink tea
     2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh
    29  polkituser:x:107:115:PolicyKit,,,:/var/run/PolicyKit:/bin/false
    30  haldaemon:x:108:116:Hardware abstraction layer,,,:/var/run/hald:/bin/false
    31  gdm:x:109:117:Gnome Display Manager:/var/lib/gdm:/bin/false

例6:在 /etc/passwd 的第2行后面加入2行字,例如 Drink tea or ..... drink beer?

$nl /etc/passwd | sed '2a Drink tea or ......\
> drink beer ?'

输入之后,输出如下:

     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
Drink tea or ......
drink beer ?
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     ...后面内容由于篇幅原因省略...

注意这里,'\'后面要紧接着回车才行。我们可以新增不只一行,但是每一行之间都必须要以反斜线 \ 来进行新行的增加。

例7: 将 /etc/passwd 的第 3-28 行的内容取代成为 No 3-28 number

$nl /etc/passwd | sed '3,28c No 3-28 number'

输入之后,输出如下:

     1  root:x:0:0:root:/root:/bin/bash
     2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh
No 3-28 number
    29  polkituser:x:107:115:PolicyKit,,,:/var/run/PolicyKit:/bin/false
    30  haldaemon:x:108:116:Hardware abstraction layer,,,:/var/run/hald:/bin/false
    31  gdm:x:109:117:Gnome Display Manager:/var/lib/gdm:/bin/false

例8: 仅列出 /etc/passwd 的第 5-7

$nl /etc/passwd | sed -n '5,7p'

输入之后,输出如下:

5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6  sync:x:5:0:sync:/sbin:/bin/sync
7  shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

注意,一定要加上 -n 参数,否则输出如下:

1  root:x:0:0:root:/root:/bin/bash
2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh
...由于篇幅原因,省略...
5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6  sync:x:5:0:sync:/sbin:/bin/sync
6  sync:x:5:0:sync:/sbin:/bin/sync
7  shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
7  shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8  polkituser:x:107:115:PolicyKit,,,:/var/run/PolicyKit:/bin/false
...由于篇幅原因,省略...

由此可知, -n 选项使得仅显示 sed 处理过的行。

例9: 仅显示 ifconfig 结果中 eth0IP

假设命令 $ifconfig 的输出如下:

eth0      Link encap:Ethernet  HWaddr 00:51:FD:52:9A:CA
          inet addr:192.168.1.12  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::250:fcff:fe22:9acb/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

那么我们用以下输入:

$ifconfig eth0|grep 'inet'|sed 's/^.*addr://g'|sed 's/Bcast.*$//g'

输入之后,输出如下:

192.168.1.12

这里,将每个管线 '|' 的过程都分开来执行

  • 先用 ifconfig eth0 列出输出
  • grep 获得有 inet 的行
  • 用 sed 's/^.*addr://g'grep 获得的行去掉ip地址前面的部分
  • 用sed 's/Bcast.*$//g'去掉ip地址后面的部分。

/etc/man.config 档案的内容中,有 MAN 的设定就取出来,但不要说明内容

$cat /etc/man.config | grep 'MAN'| sed 's/#.*$//g' |sed '/^$/d'

注意,每一行当中,若有 # 表示该行为批注,但是要注意的是,有时候,批注并不是写在第一个字符,亦即是写在某个指令后方,如下的模样: shutdown -h now # 这个是关机的指令 ,批注 # 就在指令的后方了。因此,我们才会使用到将 #.*$ 这个正规表示法。

另外这里, 使用 sed '/^$/d' 来删除空行。

利用 sed 直接在 ~/.bashrc 最后一行加入 # This is a test

$sed -i '$a # This is a test'  ~/.bashrc

注意: -i 参数可以让你的 sed 直接去修改后面接的档案内容, $a 则代表最后一行才新增的意思,结果导致新增一行,如果没有 -i ,则将 ~/.bashrc 全部显示并追加 #This is a test ,但是并不改变文件内容。

描述

参数:

  • -n :使用安静( silent )模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到屏幕上。但如果加上 -n 参数后,则只有经过 sed 特殊处理的那一行(或者动作)才会被列出来。(见例8)
  • -e :直接在指令列模式上进行 sed 的动作编辑;
  • -f :直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的 sed 动作;
  • -rsed 的动作支持的是延伸型正规表示法的语法。(预设是基础正规表示法语法)
  • -i :直接修改读取的档案内容,而不是由屏幕输出(见例11)。

动作说明: [n1[,n2]]function

  • n1, n2 :不见得会存在,一般代表『选择进行动作的行数』,举例来说,如果我的动作是需要在 10 到 20 行之间进行的,则『 10,20[动作行为] 』

function 有底下这些:

  • a :新增, a 的后面可以接字符串,而这些字符串会在新的一行出现(目前的下一行)。
  • c :取代, c 的后面可以接字符串,这些字符串可以取代 n1,n2 之间的行!
  • d :删除,因为是删除啊,所以 d 后面通常不接任何字符;
  • i :插入, i 的后面可以接字符串,而这些字符串会在新的一行出现(目前的上一行);
  • p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运作。(见例8)
  • s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 。

其它

参考资料: 《鸟哥的私房菜》