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 脚本命令,暂不学习此参数。