目录
23.单行内执行多个 sed 命令
24.sed 脚本文件
25.sed 注释
26.把 sed 当做命令解释器使用
27.直接修改输入文件
23.单行内执行多个 sed 命令
第一章内已经讲过,单行内执行多个 sed 命令有多种方法。
1. 使用多命令选项 –e
多命令选项-e 使用方法如下:
sed –e ‘command1’ –e ‘command2’ –e ‘command3’
在/etc/passwd 文件中,搜索 root、nobody 或 mail:
$ sed -n -e '/^root/ p' -e '/^nobody/ p' -e '/^mail/ p' /etc/passwd
2. 使用 \ 折行执行多个命令
在执行很长的命令,比如使用-e 选项执行多个 sed 命令时,可以使用\来把命令折到多行
sed –n –e ‘/^root/ p’ \
-e ‘/^nobody/ p’ \
-e ‘/^mail/ p’ \
/etc/passwd
3. 使用{ }把多个命令组合
如果要执行很多 sed 命令,可以使用{ }把他们组合起来执行,如:
sed –n ‘{
/^root/ p
/^nobody/ p
/^mail/ p
}’ /etc/passwd
24.sed 脚本文件
如果用重复使用一组 sed 命令,那么可以建立 sed 脚本文件,里面包含所有要执行的 sed 命
令,然后用 -f 选项来使用。
首先建立下面文件,里面包含了所有要执行的 sed 命令。前面已经解释过各个命令的含义,
现在你应该知道所有命令的意思了。
$ vi mycommands.sed
s/\([^,]*\),\([^,]*\),\(.*\).*/\2,\1, \3/g
s/^.*/<&>/
s/Developer/IT Manager/
s/Manager/Director/
现在执行脚本里面的命令 :
$ sed -f mycommands.sed employee.txt
<John Doe,101, CEO>
<Jason Smith,102, IT Director>
<Raj Reddy,103, Sysadmin>
<Anand Ram,104, IT Director>
<Jane Miller,105, Sales Director>
25.sed 注释
sed 注释以 # 开头。因为 sed 是比较晦涩难懂的语言,所以你现在写下的 sed 命令,时间一长,
再看时就不那么容易理解了。因此,建议把写脚本时的初衷作为注释,写到脚本里面。如下
所示:
$ vim mycommands.sed
#交换第一列和第二列
s/\([^,]*\),\([^,]*\),\(.*\).*/\2,\1, \3/g
#把整行内容放入<>中
s/^.*/<&>/
#把 Developer 替换为 IT Manager
s/Developer/IT Manager/
#把 Manager 替换为 Director
s/Manager/Director/
注意: 如果 sed 脚本第一行开始的两个字符是 #n 的话, sed 会自动使用 -n 选项 ( 即不自动打
印模式空间的内容 )
26.把 sed 当做命令解释器使用
一如你可以把命令放进一个 shell 脚本中,然后调用脚本名称来执行它们一样,你也可以把
sed 用作命令解释器。要实现这个功能,需要在 sed 脚本最开始加入 ”#!/bin/sed –f” ,如下所
示 :
$ vi myscript.sed
#!/bin/sed -f
#交换第一列和第二列
s/\([^,]*\),\([^,]*\),\(.*\).*/\2,\1, \3/g
#把整行内容放入<>中s/^.*/<&>/
#把 Developer 替换为 IT Manager
s/Developer/IT Manager/
#把 Manager 替换为 Director
s/Manager/Director/
现在,给这个脚本加上可执行权限 , 然后直接在命令行调用它 :
$ chmod u+x myscript.sed
$ ./myscript.sed employee.txt
<John Doe,101, CEO>
<Jason Smith,102, IT Director>
<Raj Reddy,103, Sysadmin>
<Anand Ram,104, IT Director>
<Jane Miller,105, Sales Director>
也可以指定-n 选项来屏蔽默认输出:
$ vim testscript.sed
#!/bin/sed -nf
/root/ p
/nobody/ p
/mail/ p
然后加上可执行权限,执行 :
$ chmod u+x testscript.sed
$ ./testscript.sed /etc/passwd
root:x:0:0:root:/root:/bin/bash
mail:x:8:12:Mailer daemon:/var/spool/clientmqueue:/bin/false
nobody:x:65534:65533:nobody:/var/lib/nobody:/bin/bash
处于测试目的,把 testscript.sed 里面的 -n 去掉,然后再执行一次,观察它是如何运行的。
重要提示 : 使用 -n 时,必须是 -nf. 如果你写成 -fn, 执行脚本时就会获得下面的错误 :
$ ./testscript.sed /etc/passwd
/bin/sed: couldn't open file n: No such file or directory
27.直接修改输入文件
目前为止,你知道 sed 默认不会修改输入文件,它只会把输出打印到标准输出上。当想保存
结果时,把输出重定向到文件中 ( 或使用 w 命令 ) 。
执行下面的例子之前,先备份一下 employee.txt 文件 :
$ cp employee.txt employee.txt.orig
为了修改输入文件,通常方法是把输出重定向到一个临时文件,然后重命名该临时文件 :
sed ‘s/John/Johnny/’ employee.txt > new-employee.txt
mv new-employee.txt employee.txt
相比这种传统方法,可以在 sed 命令中使用 -i 选项,使 sed 可以直接修改输入文件 :
在原始文件 employee.txt 中,把 John 替换为 Johnny:
$ sed -i 's/John/Johnny/' employee.txt
$ cat employee.txt
101, Johnny Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
再次提醒 : -i 会修改输入文件 。或许这正是你想要的,但是务必小心。一个保护性的措施是,
在 -i 后面加上备份扩展,这一 sed 就会在修改原始文件之前,备份一份。
在原始文件 employee.txt 中,把 John 替换为 Johnny ,但在替换前备份 employee.txt:
$ sed -ibak 's/John/Johnny/' employee.txt
备份的文件如下 :
$ cat employee.txtbak
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
修改后的原始文件为 :
$ cat employee.txt
101,Johnny Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
除了使用 -i, 也可以使用完整样式 –in-place. 下面两个命令是等价的 :
sed –ibak ‘s/John/Johnny/’ employee.txt
sed –in-place=bak ‘s/John/Johnny/’ employee.txt
最后,为了继续下面的例子,把原来的 employee.txt 还原回去 :
cp employee.txt.orig employee.txt
资料来源于《SedandAwk101Hacks》,大家有兴趣可以买一本,也可以关注我,我更新完它。
曾经,我花费大半月将它们跑完,现在啥都忘了,还是要常用。
只为学习交流,不为获利,侵权联系立删。