sed命令学习

sed 命令的主要功能,是替换、删除、打印和追加数据,这里就从功能出发,以案例辅助来学习 sed 命令的常用方法。

替换

[dmdba@192 my_shell]$ cat a.log 
this this this
[dmdba@192 my_shell]$ sed 's/this/This/' a.log 
This this this
[dmdba@192 my_shell]$ sed 's/this/This/g' a.log 
This This This
[dmdba@192 my_shell]$ sed 's/this/This/3g' a.log 
this this This
[dmdba@192 my_shell]$ sed -i 's/this/This/3g' a.log 
[dmdba@192 my_shell]$ cat a.log 
this this This
[dmdba@192 my_shell]$ sed -i 's/this/This/g' a.log 
[dmdba@192 my_shell]$ cat a.log
This This This
[dmdba@192 my_shell]$ sed 's:This:this:3g' a.log 
This This this
[dmdba@192 my_shell]$ sed 's|This|this|2g' a.log 
This this this
[dmdba@192 my_shell]$ sed 's|This|this|2' a.log 
This this This
[dmdba@192 my_shell]$ vi a.log 
[dmdba@192 my_shell]$ cat a.log 
This:This:This
[dmdba@192 my_shell]$ cat a.log |sed 's/This/this/2'
This:this:This
[dmdba@192 my_shell]$ cat a.log |sed 's/\:This/\|this/2'
This:This|this

在上面的案例中,包含了以下内容:
  1.sed 替换参数为 s ,通常为 s/.../.../ 的结构,添加了 -i 参数后,是会替换进文本 a.log 中的,否则只是将替换后的结果输出,不会写入文本;
  2.默认使用的 / 被称为定界符,最后一个定界符后面没有参数,则只会替换每行的第一个匹配对象;添加数字 n,则会替换第 n 个匹配对象;添加 g,则会替换所有匹配对象;同理,ng 则是替换大于等于第 n 个匹配的所有对象;
  3.一般是使用 / 作为定界符,但是也可以使用其他定界符,如 : , | 等;
  4.当要替换的对象中包含定界符时,需要使用反斜杠 \ 进行转义。

  特殊替换用法

[dmdba@192 my_shell]$ cat a.log 
I want a Pikachu
[dmdba@192 my_shell]$ cat a.log |sed 's/\w\+/[&]/g'
[I] [want] [a] [Pikachu]
[dmdba@192 my_shell]$ cat a.log |sed 's/\w\+/(&)/g'
(I) (want) (a) (Pikachu)
[dmdba@192 my_shell]$ cat a.log 
I want a Pikachu
[dmdba@192 my_shell]$ cat a.log | sed 's/\([a-zA-Z]\+\) \([a-zA-Z]\+\) \([a-zA-Z]\+\) \([a-zA-Z]\+\)/\4 \2 \3 \1/'
Pikachu want a I
[dmdba@192 my_shell]$ cat a.log | sed 's/a \([a-zA-Z]\+\)/\1/'
I want Pikachu

以上案例中,是对字符串的标记方法。
  1.\w\+ 表示匹配每一个单词,而 & 表示匹配之前匹配到的对象;
  2.\(...\) 是一种标记方法,案例中 \([a-zA-Z]\+\) 是正则表达式的匹配方式,表示匹配一个或多个英文字母组成的对象,其中 ()+ 需要转义,第一个匹配的是 \1 ,第二个则是 \2 ,最多可以标记9个,可以调换标记对象的顺序,也可以将其替换掉。

删除

[dmdba@192 my_shell]$ cat a.log 
first row

second row

last row
[dmdba@192 my_shell]$ sed '/^$/d' a.log 
first row
second row
last row
[dmdba@192 my_shell]$ sed '2d' a.log 
first row
second row

last row
[dmdba@192 my_shell]$ sed '2,$d' a.log 
first row
[dmdba@192 my_shell]$ sed '$d' a.log 
first row

second row

[dmdba@192 my_shell]$ sed '/^sec/d' a.log 
first row


last row
[dmdba@192 my_shell]$ sed '/^sec/'d a.log 
first row


last row

在上面的案例中,包含了以下内容:
  1.参数 d 表示删除,可以放在单引号内,也可以放在单引号后面;
  2.sed 'nd' 表示删除第 n 行,n,md表示从第 n 行到第 m 行,而 $ 符号表示最后一行;
  3.删除空白行的 '/^$/d',从意义上看,是正则规则,^ 表示一行的开头,$ 表示一行的结尾,^$ 则代表这一行为空。

打印展示

[dmdba@192 my_shell]$ cat -n a.log 
     1    root:x:0:0:root:/root:/bin/bash
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     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
     8    halt:x:7:0:halt:/sbin:/sbin/halt
     9    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    10    operator:x:11:0:operator:/root:/sbin/nologin 
[dmdba@192 my_shell]$ sed '1,2p' a.log 
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[dmdba@192 my_shell]$ sed -n '1,2p' a.log 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[dmdba@192 my_shell]$ sed -n '/sync/p' a.log 
sync:x:5:0:sync:/sbin:/bin/sync
[dmdba@192 my_shell]$ sed -n '/daemon/,/lp/p' a.log 
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[dmdba@192 my_shell]$ sed -n '/root/,/daemon/p' a.log 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

在上面的案例中,包含了以下内容:
  1.打印的参数是 p ,当默认模式时,除了将需要打印的对象打印一次以外,还会把文本全部再打印一遍;
  2.添加 -n 参数后,只打印匹配的行,'n,mp' 即表示打印从第 n 行到第 m 行,其中 n 与 m 可以是数字,也可以是包含某对象的行,如上面的案例 sed -n '/daemon/,/lp/p' a.log ,但是当匹配的对象不唯一时,匹配到的行也会被打印的,所以一般还是准确打印行或者有唯一符号定位比较方便。

追加

[dmdba@192 my_shell]$ cat a.log 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[dmdba@192 my_shell]$ sed '2a New line' a.log 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
New line
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[dmdba@192 my_shell]$ sed '/nologin/a New line' a.log 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
New line
daemon:x:2:2:daemon:/sbin:/sbin/nologin
New line
[dmdba@192 my_shell]$ sed '/nologin/i New line' a.log 
root:x:0:0:root:/root:/bin/bash
New line
bin:x:1:1:bin:/bin:/sbin/nologin
New line
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[dmdba@192 my_shell]$ sed '/nologin/i\New line\nAnother new line' a.log 
root:x:0:0:root:/root:/bin/bash
New line
Another new line
bin:x:1:1:bin:/bin:/sbin/nologin
New line
Another new line
daemon:x:2:2:daemon:/sbin:/sbin/nologin

在上面的案例中,包含了以下内容:
  1.参数 a 表示在下方追加,i 表示在上方追加;
  2.一次可以追加多行,但是要使用 \n 来分行,追加的对象可以放在 a 或 i 后空格隔开,也可以使用反斜杠隔开。

总结

sed 命令主要参数, -n 和 -i 分别表示只展示匹配行和修改入文本里;在匹配中的参数,p/g/d/s/a/i 分别表示打印,匹配所有,删除,替换,下方追加和上方追加(当然以上是个人方便记忆的粗浅总结,比如 g 参数是意义其实是 (获得内存缓冲区的内容,并替代当前模板块中的文本)。另外,常用的还有 -e ,可以执行多个 sed 命令,如。

[dmdba@192 my_shell]$ cat a.log 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[dmdba@192 my_shell]$ sed -e '3d' -ne '/sbin/p' a.log 
bin:x:1:1:bin:/bin:/sbin/nologin

  上面这个案例,通过 -e 参数,先删除第三行,第二个 -e 与 -n 写到一起,找出带有 sbin 的行并打印。
  有些操作也可以不分 -e 来分开执行,可以一次处理,比如以下案例,先匹配 bash 的行,然后在行尾添加 ` test` 。

[dmdba@192 my_shell]$ sed -n '/bash/s/$/ test/p' a.log 
root:x:0:0:root:/root:/bin/bash test

另外,sed -f 可以执行 sed 脚本命令,暂不学习此参数。 

posted @ 2019-04-28 20:52  LightInk  阅读(238)  评论(0编辑  收藏  举报