一、sed是什么?
sed全名叫stream editor,流编辑器(也叫行编辑器),其处理文本的方式为一行一行的,不同于vi等全屏编辑器;主要用途为通过匹配一个或多个正则表达式来对文本进行处理,实现过滤和转换文本。
sed 的工作方式
sed 实用工具按顺序逐行将文件读入到内存中。然后,它执行为该行指定的所有操作,并在完成请求的修改之后将该行放回到内存中,以将其转储至终端。完成了这一行 上的所有操作之后,它读取文件的下一行,然后重复该过程直到它完成该文件。如同前面所提到的,默认输出是将每一行的内容输出到屏幕上(特别要注意这点,因此一般要配合-n参数不让其显示不需要的)。在这里,开始涉及到 两个重要的因素—首先,输出可以被重定向到另一文件中,以保存变化;第二,源文件(默认地)保持不被修改。sed 默认读取整个文件并对其中的每一行进行修改。不过,可以按需要将操作限制在指定的行上。
二、基本用法:
通过man命令查看sed帮助如下:
NAME
sed - stream editor for filtering and transforming textSYNOPSIS
sed [OPTION]... {script-only-if-no-other-script} [input-file]...
用便于理解的表示其用法如下:
sed [options] 'AddressCommand' file ...
其中AddressCommand表示对需要处理的范围(地址)执行的命令
2.1 options主要有如下几个常用的:
- -n: 静默模式,不再默认显示模式空间中的内容
- -i: 直接修改原文件
- -e SCRIPT -e SCRIPT:可以同时执行多个脚本
- -f /PATH/TO/SED_SCRIPT
sed -f /path/to/scripts file
- -r: 表示使用扩展正则表达式
- -n:显示出其他资料行的默认操作,只显示符合的数据行,如下面加-n选项和不加的显示效果是不一样的:
2.2 Address
Address表示sed处理的范围,如第20到30行、以root开头的行等等。主要有如下几种:
- 指定行:StartLine,EndLine
5,30 表示第5至30行
[root@localhost ~]# sed '5,30d' /etc/passwd ##删除5至30行内容(不会修改原文件)
root:x:0:0:root:/root:/bin/bash
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
$ 表示最后一行
- 正则表达式匹配:/RegExp/
sed正则表达式的用法基本与grep一样,如:
[root@localhost ~]# sed '/nologin$/d' /etc/passwd ##删除以nologin结尾的行
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
barlow:x:500:500::/home/barlow:/bin/bash
- /pattern1/,/pattern2/
第一次被pattern1匹配到的行开始,至第一次被pattern2匹配到的行结束,这中间的所有行
- 指定具体的行:LineNumber
- 从某行开始及后面的多少行:addr1,+N
上面的5,30 等于5,+25
[root@localhost ~]# sed '5,+25d' /etc/passwd
root:x:0:0:root:/root:/bin/bash
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
三、Command
在将Command之前,需要再次强调的是,Address和Command之间是直接相连的,中间没有空格或者其他符号。
Command主要有如下这些:
- d: 删除符合条件的行;参见前面Address部分的示例。
- p: 显示符合条件的行;需要注意的是,文章第二段红字部分已经强调了,sed默认会把处理的文本一行行输出到终端,因此直接用p命令看不出什么效果。
- a \string: 在指定的行后面追加新行,内容为string,如下面的例子将在文本最后添加一行内容,注意cat看到结果与sed处理结果的差异:
- \n:可以用于换行
- i \string: 在指定的行前面添加新行,内容为string
- r FILE: 将指定的文件的内容添加至符合条件的行处,如在fstab第二行后添加issue文件的内容
- w FILE: 将地址指定的范围内的行另存至指定的文件中;
- s/pattern/string/修饰符: 查找并替换,默认只替换每行中第一次被模式匹配到的字符串
修饰符主要有:
g: 全局替换
i: 忽略字符大小写
注意,替换命令的三个/可以用其他字符替换,如:
s@pattern@string@修饰符
s#pattern#string#修饰符
这些都是可以的,只要三个分隔符一样即可。
sed的查找替换功能参照我以前的博文:Linux下使用sed命令替换文件文件内容
- &: 引用模式匹配整个串
四、常用用法示例:
1、删除行首空格
[root@localhost ~]# sed 's/^[ ]*//g' filename
[root@localhost ~]# sed 's/^ *//g' filename
[root@localhost ~]# sed 's/^[[:space:]]*//g' filename
2、行后和行前添加新行
行后:
[root@localhost ~]# sed 's/pattern/&\n/g' filename
行前:
[root@localhost ~]# sed 's/pattern/\n&/g' filename
注意:&代表pattern
3、使用变量替换(使用双引号)
[root@localhost ~]# sed -e "s/$var1/$var2/g" filename
4、在第一行前插入文本
sed -i '1 i\插入字符串' filename
5、在最后一行插入
[root@localhost ~]# sed -i '$ a\插入字符串' filename
6、在匹配行前插入
[root@localhost ~]# sed -i '/pattern/ i "插入字符串"' filename
7、在匹配行后插入
[root@localhost ~]# sed -i '/pattern/ a "插入字符串"' filename
8、删除文本中空行和空格组成的行以及#号注释的行
[root@localhost ~]# grep -v '^#' filename | sed '/^[[:space:]]*$/d'
9、处理命令结果中的多余空格,将df结果中多个空格分隔的替换为一个:分隔
[root@localhost ~]# df -P |sed -r 's/[[:space:]]+/:/g'
##-P 选项表示df输出信息不自动换行
##[[:space:]]+匹配表示空格至少出现一次