概述
sed
命令是一个流编辑器,用于对输入流(一个文件或者来自管道的输入)执行基本的文本转换,如对文件进行添加、替换、删除、选取等功能。它可以像编辑器一样处理文本,还可以通过管道符来处理输入流,而且对输入进行一次传递来工作,因此效率较高。
用法
sed [options] [action] [filename]
常用options
-n:表示使用安静模式,一般sed命令将会打印出所有的来自stdin的数据,如果指定-n,则仅仅会打印指定的数据
-e:直接在命令行模式上进行sed的动作编辑,默认选项。
-f:后跟一个文件名,将sed的动作写在一个文件内,-f filenem就会执行该文件内的sed动作
-r:动作使用扩展正则语法,默认基础正则语法
-i:修改文件内容,而不再由屏幕输出
action格式:
[n1,n2]function
n1,n2表示行数
a:后跟字符串,表示在当前行尾新增该字符串;
i:后跟字符串,表示在当前行尾新增该字符串;
d:表示删除,不接任何参数
p:表示打印,一般和-n搭配使用
s:表示替换一般以s/old/new/g的形式使用
示例
现在对于以上命令逐个进行练习,首先复制一份/etc/passwd
文件,以该文件进行练习:
sed -n [n1,n2]p
该命令用于打印指定的行数内容,如果要打印2-5行的内容,则如下所示:
# 打印2-5行的内容
jyq@ubuntu:~/shellstudy$ cat passwd |sed -n '2,5p'
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
jyq@ubuntu:~/shellstudy$
sed [-e] [n1,n2][aidcs]
-e
为默认选项,因此可以不指定。
如果要删除2-5行内容,则使用sed 'd'
:
# 删除2-5行内容
jyq@ubuntu:~/shellstudy$ cat -n passwd | sed -e '2,5d'
1 root:x:0:0:root:/root:/bin/bash
6 games:x:5:60:games:/usr/games:/usr/sbin/nologin
7 man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
8 lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
9 mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
10 news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
11 uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
# ......
如果要在第二行后追加一个”just do it “字符串,则如下所示:
# a表示追加字符串
jyq@ubuntu:~/shellstudy$ cat -n passwd | sed '2a just do it'
1 root:x:0:0:root:/root:/bin/bash
2 daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
just do it
3 bin:x:2:2:bin:/bin:/usr/sbin/nologin
4 sys:x:3:3:sys:/dev:/usr/sbin/nologin
5 sync:x:4:65534:sync:/bin:/bin/sync
#......
如果要在第二行前追加一个”just do it “字符串,则如下所示:
# i表示在当前行之前插入字符串
jyq@ubuntu:~/shellstudy$ cat -n passwd | sed -e '2i just do it'
1 root:x:0:0:root:/root:/bin/bash
just do it
2 daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
3 bin:x:2:2:bin:/bin:/usr/sbin/nologin
4 sys:x:3:3:sys:/dev:/usr/sbin/nologin
5 sync:x:4:65534:sync:/bin:/bin/sync
# ......
如果要将第4-6行内容替换为”just do it”,则使用sed c'
:
# c表示替换
jyq@ubuntu:~/shellstudy$ cat -n passwd | sed '4,6c just do it'
1 root:x:0:0:root:/root:/bin/bash
2 daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
3 bin:x:2:2:bin:/bin:/usr/sbin/nologin
just do it
7 man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
再来看看如何替换某一个指定内容,在上面说过了,替换时使用sed 's/old/new/g'
的形式,比如将前三行中的”root”替换为”ROOT”:
# 替换root为ROOT
jyq@ubuntu:~/shellstudy$ head -n 3 passwd | sed 's/root/ROOT/g'
ROOT:x:0:0:ROOT:/ROOT:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
jyq@ubuntu:~/shellstudy$
还可以使用正则表达式进行来进行替换,如:
# 表示将/开始到结尾的数据全部使用空替换,相当于删除
jyq@ubuntu:~/shellstudy$ head -n 3 passwd | sed 's/\/.*$//g'
root:x:0:0:root:
daemon:x:1:1:daemon:
bin:x:2:2:bin:
jyq@ubuntu:~/shellstudy$
sed -i [aidcps] filename
如果直接对文件进行操作,则使用该命令,
比如,将passwd
文件中的冒号:直接改为两个加号++,则使用sed -i 's/:/++/g' passwd
:
# -i参数表示直接操作文件,单引号中表示操作动作
jyq@ubuntu:~/shellstudy$ sed -i 's/:/++/g' passwd
jyq@ubuntu:~/shellstudy$ head -n 5 passwd
root++x++0++0++root++/root++/bin/bash
daemon++x++1++1++daemon++/usr/sbin++/usr/sbin/nologin
bin++x++2++2++bin++/bin++/usr/sbin/nologin
sys++x++3++3++sys++/dev++/usr/sbin/nologin
sync++x++4++65534++sync++/bin++/bin/sync
jyq@ubuntu:~/shellstudy$
再比如,在passwd文件最后添加一个”just do it “的字符串:
# $表示最后一行
jyq@ubuntu:~/shellstudy$ sed -i '$a just do it' passwd
jyq@ubuntu:~/shellstudy$ tail -n 5 passwd
guest-i7wnah++x++994++994++Guest++/tmp/guest-i7wnah++/bin/bash
guest-j0rrk1++x++993++993++Guest++/tmp/guest-j0rrk1++/bin/bash
guest-pmoc50++x++992++992++Guest++/tmp/guest-pmoc50++/bin/bash
guest-eopm1h++x++991++991++Guest++/tmp/guest-eopm1h++/bin/bash
just do it
jyq@ubuntu:~/shellstudy$
sed -f filename
该命令表示sed将读取filename中的动作,因此filename中只能是sed的动作,如:
# 首先创建一个sedfile文件,文件内容如下
# 删除4-8行
4,8d
# 替换1-3行
1,3c Just do it
# 执行sed -f sedfile,将读取sedfile中的action并执行
jyq@ubuntu:~/shellstudy$ cat -n passwd |sed -f sedfile
Just do it
9 mail++x++8++8++mail++/var/mail++/usr/sbin/nologin
10 news++x++9++9++news++/var/spool/news++/usr/sbin/nologin
11 uucp++x++10++10++uucp++/var/spool/uucp++/usr/sbin/nologin
12 proxy++x++13++13++proxy++/bin++/usr/sbin/nologin
sed -r action
默认sed仅支持基础正则表达式,如果要使用扩展正则表达式语法,则需要使用sed -r
,比如,我们要将passwd文件中”root”和”guest”都替换为”USER”,如果不指定-r
:
jyq@ubuntu:~/shellstudy$ cat passwd |sed 's/root/USER/g' |sed 's/guest/USER/g'
USER:x:0:0:USER:/USER:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
......
USER-6xfruk:x:999:999:Guest:/tmp/USER-6xfruk:/bin/bash
sshd:x:121:65534::/var/run/sshd:/usr/sbin/nologin
USER-efctx2:x:998:998:Guest:/tmp/USER-efctx2:/bin/bash
USER-tfmlhr:x:997:997:Guest:/tmp/USER-tfmlhr:/bin/bash
USER-tgjyur:x:996:996:Guest:/tmp/USER-tgjyur:/bin/bash
USER-swm7od:x:995:995:Guest:/tmp/USER-swm7od:/bin/bash
可以看到,必须使用管道命令sed
两次;如果使用sed -r
,则只需要一次即可:
jyq@ubuntu:~/shellstudy$ cat passwd |sed -r 's/root|guest/USER/g'
USER:x:0:0:USER:/USER:/bin/bash
......
USER-efctx2:x:998:998:Guest:/tmp/USER-efctx2:/bin/bash
USER-tfmlhr:x:997:997:Guest:/tmp/USER-tfmlhr:/bin/bash
USER-tgjyur:x:996:996:Guest:/tmp/USER-tgjyur:/bin/bash
扩展正则表达式的|
表示”或”。
参考资料
《鸟哥的Linux私房菜》