sed适合文件修改比较大的情况,vim或gedit适合小处修改。
sed命令支持的三种操作,即打印、删除和替换
sed是一个流编辑器,它可以对从标准输入流中得到的数据进行处理,然后把处理以后得到的结果输出到标准输出,而标准输出通常会关联到终端屏幕,因此处理后的结果也会显示到屏幕上。当然,也可以把标准输出重定向到文件,这样处理后的结果就保存在磁盘文件中。注意,sed只会对流经它的数据流进行处理和编辑,而不会对原始文件做任何修改,这就意味着要处理的数据并不一定非要是磁盘上的文件,也可以是其他进程的数据输出。
案例1:将HTML页面中的email地址从jerry@zulmma.com改为emma@zulmma.com
index.html内容:
Email me!
Page created by:jerry@zulmma.com
copyright @2012 mysite!
modify_webpage.sh的内容如下:
#!/bin/bash#处理命令行的每一个文件,可以使用通配符for file in "$@"do echo "**PRocessing $file**" #保存结果到临时文件中 sed 's/jerry@zulmma.com/emma@zulmma.com/g' "$file" > "$file.$$" if [ -f $file.$$ ] then #覆盖原始文件mv -f "$file.$$" "$file" fidone echo " All Done."exit 0
sed命令通常有两种调用形式:
#sed程序从管道中读取输入数据
$some_command | sed ‘edit commands’
#sed程序使用命令行参数读取文件内容,而不是从标准输入中读取
$sed ‘edit commands’ files
案例2:使用sed编辑多个命令,有以下两个方法:
l 使用分号连接多个编辑命令
sed ‘s/command1/command2/g;s/command3/command4/g’ files
l 使用选项-e指定多个编辑命令
sed –e ‘s/command1/command2/g’ –e ‘s/command3/command4/g’files
案例3:修饰符I或i大小写不敏感匹配
$sed ‘s/command1/command2/gi’ files
除了这两个修饰符以外,替换命令还接收如下修饰符:
修饰符 | 含义 |
num | 只取代第num个匹配 |
p | 如果匹配成功,打印模式空间 |
w FILENAME | 如果匹配成功,把结果写到文件FILENAME中 |
g | 全局匹配,而不是只替换第一个匹配 |
I or i | 用大小写不敏感的匹配 |
案例4:若干替换命令的字符中含有分隔符,需要给它转义。
若只想要操作的行,有两种方法:
l 正则表达式匹配的行
l 地址指定sed命令要操作的行
所谓地址就是文本文件的行号,要么是一个文件中的特定行,要么是一个范围。如果在编辑命令中没有指定地址,则sed命令会对每一行都执行编辑操作。
案例1:删除或打印某一行或某范围的所有行
#从文件中删除一行
$cat –n /etc/passwd | sed ‘11d’ | more
#从文件中删除一个范围的行数据
$cat –n /etc/passwd | sed ‘3,26d’
#打印文件某行
$cat –n /etc/passwd | sed –n ‘11p’
打印文件某些行
$cat –n /etc/passwd |sed –n ‘3,26p’
#打印第3行及后面的3行数据
$cat –n /etc/passwd | sed –n ‘3,+3p’
解析:cat –n作用是在每行前面添加行号;编辑命令d是表示行;sed命令的默认行为是输出所有的行数据,选项-n关闭这个默认行为;编辑命令p是明确告诉sed命令打印某些行;+num表示从起始行开始,后面的多少行在这个范围内。
案例2:打印文件/etc/passwd中范围之外的行
#使用感叹号!对地址范围取反
$cat –n /etc/passwd | sed –n ‘3,26!p’
解析:感叹号!可以对某行或某范围取反;
案例3:打印出/etc/passwd文件中所有单数行数据
#打印每一个奇数行
$cat –n /etc/passwd | sed –n ‘1~2p’
解析:使用address stepping的寻址方式。’1~2p’,1是起始地址,2p表示从上一次操作的行增加2行;
案例4:希望删除配置文件/etc/sysctl.conf中的所有注释行
#删除文件/etc/sysctl.conf中的所有注释行
$cat /etc/sysctl.conf | sed ‘/^#/d’
案例5:打印/etc/sysctl.conf文件中以数字结尾的行
#找到所有以数字结尾的行
$cat /etc/sysctl.conf | sed –n ‘/[0-9]$/p’
正则表达式可以指定字符的范围:
集合 | 含义 |
[a-z] | 匹配一个小写字母 |
[A-Z] | 匹配一个大写字母 |
[a- zA-Z] | 匹配一个字母 |
[a- zA-Z0-9] | 匹配一个字母或数字 |
案例6:希望打印/etc/sysctl.conf文件中从’# Do not accept ICMP’开始,到’# Log Martian Packets’之间的内容
#使用正则表达式匹配确定要匹配的行范围
$cat /etc/sysctl.conf | sed –n ’/^# Do notaccept ICMP/,/^# Log Martian Packets/p’
#还可以将行号与正则表达式混合使用
$cat /etc/sysctl.conf | sed –n ’17,/^# LogMartian Packets/p’
在sed命令中,正则表达式除了可以确定操作的行以外,还可以在替换命令中匹配希望被替换的字符串。
案例1:
#使用正则表达式所有的空行替换字符#
$cat /etc/sysctl.conf | sed ‘s/^$/#/’
案例2:
#在/etc/sysctl.conf文件中的所有非注释行前都添加一个#字符进行注释
$cat /etc/sysctl.conf | sed ‘s/^[^#].*$/#&/’
刚开始你可能会认为学习sed命令的使用会浪费很多时间,但是当你花费了一些时间真正掌握了它以后,你会发现这些时间和努力是非常值得的。sed命令是一个强大的流编辑器,它可以为我们自动执行大量枯燥繁琐的编辑操作。执行sed命令时有一个模式空间的概念,本质上它就是一个工作缓存,sed命令每处理一行数据都会先把数据读入这个缓存中,然后再按照顺序执行所指定的编辑命令来处理这些数据。
本章的重要知识点包括:
(1)sed命令的工作原理;
(2)如何避免sed命令默认打印模式缓存;
(3)什么是正则表达式;
(4)如何使用正则表达式匹配行的开头和结尾,如何匹配一个字符和任意个字符;
(5)如何使用sed命令替换字符串;
(6)选择要操作行的几种方式;
(7)如何在替换命令中使用正则表达式匹配要替换的字符串;
(8)如何在替换命令中引用正则表达式匹配到的结果。
新闻热点
疑难解答