SED是一种流编辑器工具,可以根据设置的匹配条件对文件内容进行处理,支持正则表达式。sed每次处理一行数据,和awk处理流程是一样的。
sed命令格式:
sed [options] '/pattern/command' file #如果有引用变量的话需要使用双引号
sed命令常用选项[options]部分:
-r:支持扩展正则表达式,如+、|、()等特殊符号
cat file | sed -nr '/=+/p' #打印出包含一个或多个=号的行
-i:不加-i时所作的操作都是不会修改源文件的,如果要修改源文件的话就需要加上这个参数
这里有个备份文件的小技巧:为避免误操作直接覆盖了源文件,我们可以在加-i的时候加上.bak,然后就会自动生成一个以.bak结尾的备份文件,如图:
-n:不显示默认输出。由于sed默认会把所有行都输出,不管是修改的还是不修改的。加上-n选项,就可以关闭输出信息,在匹配条件最后加p标签就可以只显示出我们修改过的内容,比如单独显示某一行数据cat file | sed -n '4p'。
-e:多重匹配,第二次匹配时模式空间里的数据是第一次替换后的
sed -e 's/tom/TOM/' -e 's/tom/jerry/' /etc/passwd
##由于第一次匹配时把tom换成了TOM,第二次就不存在tom字段,所以不会再替换为jerry
sed 's/tom/TOM/;s/tom/jerry/' /etc/passwd #分号也可以代替-e选项
sed命令定址[pattern]部分:
sed可以使用正则表达式进行定址,定址决定sed需要处理的内容范围,sed定址示例
# 10command 仅匹配第10行
# 10,20command 匹配10到20行
# 10,+5command 在10行的位置再多打印三行
# /pattern1/command 根据正则进行匹配
# /pattern1/,/pattern2/command 从第一个正则内容匹配到第二个正则内容出现的地方
sed -n '17p' 1.txt #打印17行
sed -n '10,20p' 1.txt #打印10-20行
sed -n '/root/p' 1.txt #打印包含root的行
sed -n '/14:00/,/14:30/p' /var/log/messages #过滤指定日期的日志
sed命令[command]部分:
命令决定了需要执行的动作,默认为p,表示打印出匹配出来的内容。所以写sed语句的话可以按照“将x行到y行中带有z字符的内容做a操作”
删除命令——d。
2d代表删除第二行内容
2,5d,删除第二到第五行。2;5d删除第2和第5行
s——替换命令
用///或###(任意成对的符号都可以)这样的框架来引用需要替换的和替换后的内容,如s/old/new/或s#old#new#这两种写法都可以把old一词替换为new,默认只替换每行第一个,如果想要每行替换,可以写为s/old/new/g,g代表全局。old部分可以用正则表达式匹配,new不可以。如:
sed '1,2s/tom/TOM/g' /etc/passwd,把第一第二行的tom替换为TOM
sed '/root/s/root/ROOT/' /etc/passwd,匹配包含root的行,并把root替换ROOT
q——退出命令
由于sed工作模式是将文件的每一行都处理后再进行输出,那么当遇到处理巨大文件时就会耗费很多时间,这可能是不必要的,比如我们明确只需要处理该文件的前100行。这个时候就可以用上该选项了,示例:
cat bigfile | sed '1,100d;100q' #处理到第100行后就退出
a——在指定行后面追加一行内容
i——在指定行前面追加一行
cat shell.sh | sed -i '1i#!/bin/bash' #给脚本增加一行注释
sed的后项引用:
括号内的部分可以在后面直接被引用,第一个括号内的内容是\1,依次类推,也可以使用&符号代表前面所匹配到的所有内容。后项引用可用于更换文本内容的位置或者批量添加注释等
cat /etc/fstab | sed -nr 's/(.*)(mysql)(.*)/\3\2\1/gp'
sed -r '3,5s/.*/#&/' /etc/fstab
sed -ir '1,10s/^/#/' /etc/fstab #批量增加注释的最简洁办法
sed -r 's/(.)(.)(.*)/\1\2#\3/' /etc/fstab #在每行第二个字母前加注释