Contents
3.8. 8 三剑客之sed¶
3.8.1. 概念¶
sed是一种流编辑的文本处理工具, * 工作模式:将当前处理的行存储在临时缓冲区(模式空间),对缓冲区中的内容利用制定的动作进行处理,完成后输出到屏幕,接着反复重复执行此操作完成整改文件的处理。
3.8.2. 适用场景¶
大文件
有规律的文本
3.8.3. 语法¶
sed [option] ‘Addresscommand’ [file …]
选项
* -n:安静模式,仅显示script处理后的结果,不再默认显示模式空间中的内容
* -e:<script>或--expression=<script> 以选项中指定的script来处理输入的文本文件,可以同时执行多个脚本
* -f:对制定的文件直接进行sed的command操作
* -i:直接修改原文件
* -r:支持扩展正则表达式
地址定界
* startline,endline * /regexp/ * /pattern1/,/pattern2/:第一次被pattern1匹配到的行开始,直到被pattern2匹配到的行结束 * linenuber:制定行号 * startline,+n,从startline开始,向后n行结束 * startline~step:步长,每隔step步
命令操作
* d: 删除符合条件的行;
* p: 显示符合条件的行;
* a \string: 在制定或匹配到的行后面追加新行,内容为string
* \n:可以用于换行
* i \string: 在制定或匹配到的行前面添加新行,内容为string
* s:s/pattern/string/修饰符: 查找并替换,默认只替换每行中第一次被模式匹配到的字符串
加修饰符
* g: 全局替换
* i: 忽略字符大小写
匹配元字符:
^ 匹配行开始,如:/^sed/匹配所有以sed开头的行。
$ 匹配行结束,如:/sed$/匹配所有以sed结尾的行。
. 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。
* 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
[] 匹配一个指定范围内的字符,如/[ss]ed/匹配sed和Sed。
[^] 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
\(..\) 匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。
& 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。
\< 匹配单词的开始,如:/\<love/匹配包含以love开头的单词的行。
\> 匹配单词的结束,如/love\>/匹配包含以love结尾的单词的行。
x\{m\} 重复字符x,m次,如:/0\{5\}/匹配包含5个0的行。
x\{m,\} 重复字符x,至少m次,如:/0\{5,\}/匹配至少有5个0的行。
x\{m,n\} 重复字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10个0的行。
3.8.4. 使用举例¶
1、删除/etc/grub.conf文件中行首的空白符;
sed -r 's/^[[:space:]]+//g' /etc/grub.conf
2、替换/etc/inittab文件中"id:3:initdefault:"一行中的数字为5;
's/id:[0-9]/id:5/g' /etc/inittab
3、删除/etc/inittab文件中注释行:
sed '/^#/d' /etc/inittab
4、取消/etc/inittab文件中开头的#号;
sed 's/^#//g' /etc/inittab
5、打印文件/etc/services匹配blp5开头的行
sed -n '/^blp5/p' /etc/services
6、打印2-5行
sed -n '2,5p' /etc/services
7、打印奇数行
seq 10 |sed -n '1~2p'
8、打印最后一行
sed '$p' /etc/services
9.删除文件info_num.txt的第1~4行中匹配模式/etc\./(即含有字符串“etc.”)的行:
sed '1,4{/etc\./d}' info_num.txt
10.将文件techClass.txt的第1行的内容写入文件output.txt
sed -n '1w output.txt' techClass.txt
11.将文件techClass.txt的第1行和最后一行的内容写入文件output.txt
sed -n -e '1w output.txt' -e '$w output.txt' techClass.txt
sed 10q # 显示文件中的前10行 (模拟"head -10")
sed -n '$=' # 计算行数(模拟 "wc -l")
sed -n '5,/^no/p' # 打印从第5行到以no开头行之间的所有行sed '/^$/d' mail.txt #删除空行
sed -i "/^$f/d" a # 删除匹配行
sed -i "s/=/:/" c # 直接对文本替换
sed -i "/^pearls/s/$/j/" # 找到pearls开头在行尾加j
sed '/1/,/3/p' file # 打印1和3之间的行
sed -n '1p' 文件 # 取出指定行
sed '5i\aaa' file # 在第5行之前插入行
sed '/Databases/a\ > Solaris - Sysadmin, Recovery etc.' info.txt #在匹配模式“Databases”的行之后加入一行“Solaris-Sysadmin, Recovery etc.”
sed '$a\ > Solaris - Sysadmin, Recovery etc.\ > Windows - Sysadmin etc.' info.txt #在文件info.txt的最后一行之后添加两行内容
sed '3i\ > Solaris - Sysadmin, Recovery etc.' info.txt #在文件info.txt的第3行之前插入一行“Solaris - Sysadmin, Recovery etc.”
sed '5a\aaa' file # 在第5行之后抽入行
echo a|sed -e '/a/i\b' # 在匹配行前插入一行
echo a|sed -e '/a/a\b' # 在匹配行后插入一行
echo a|sed 's/a/&\nb/g' # 在匹配行后插入一行
seq 10| sed -e{1,3}'s/./a/' # 匹配1和3行替换
sed -n '/regexp/!p' # 只显示不匹配正则表达式的行
sed '/regexp/d' # 只显示不匹配正则表达式的行
sed '$!N;s/\n//' # 将每两行连接成一行
sed '/baz/s/foo/bar/g' # 只在行中出现字串"baz"的情况下将"foo"替换成"bar"
sed '/baz/!s/foo/bar/g' # 将"foo"替换成"bar",并且只在行中未出现字串"baz"的情况下替换
echo a|sed -e 's/a/#&/g' # 在a前面加#号
sed 's/foo/bar/4' # 只替换每一行中的第四个字串
sed 's/\(.*\)foo/\1bar/' # 替换每行最后一个字符串
sed 's/\(.*\)foo\(.*foo\)/\1bar\2/' # 替换倒数第二个字符串
sed 's/[0-9][0-9]$/&5' # 在以[0-9][0-9]结尾的行后加5
sed -n ' /^eth\|em[01][^:]/{n;p;}' # 匹配多个关键字
sed -n -r ' /eth|em[01][^:]/{n;p;}' # 匹配多个关键字
echo -e "1\n2"|xargs -i -t sed 's/^/1/' {} # 同时处理多个文件
sed '/west/,/east/s/$/*VACA*/' # 修改west和east之间的所有行,在结尾处加*VACA*
sed 's/[^1-9]*\([0-9]\+\).*/\1/' # 取出第一组数字,并且忽略掉开头的0
sed -n '/regexp/{g;1!p;};h' # 查找字符串并将匹配行的上一行显示出来,但并不显示匹配行
sed -n ' /regexp/{n;p;}' # 查找字符串并将匹配行的下一行显示出来,但并不显示匹配行
sed -n 's/\(mar\)got/\1ianne/p' # 保存\(mar\)作为标签1
sed -n 's/\([0-9]\+\).*\(t\)/\2\1/p' # 保存多个标签
sed -i -e '1,3d' -e 's/1/2/' # 多重编辑(先删除1-3行,在将1替换成2)
sed -e 's/@.*//g' -e '/^$/d' # 删除掉@后面所有字符,和空行
sed -n -e "{s/文本(正则)/替换的内容/p}" # 替换并打印出替换行
sed -n -e "{s/^ *[0-9]*//p}" # 打印并删除正则表达式的那部分内容
echo abcd|sed 'y/bd/BE/' # 匹配字符替换
sed '/^#/b;y/y/P/' 2 # 非#号开头的行替换字符
sed '/suan/r 读入文件' # 找到含suan的行,在后面加上读入的文件内容
sed -n '/no/w 写入文件' # 找到含no的行,写入到指定文件中
sed '/regex/G' # 在匹配式样行之后插入一空行
sed '/regex/{x;p;x;G;}' # 在匹配式样行之前和之后各插入一空行
sed 'n;d' # 删除所有偶数行
sed 'G;G' # 在每一行后面增加两空行
sed '/^$/d;G' # 在输出的文本中每一行后面将有且只有一空行
sed 'n;n;n;n;G;' # 在每5行后增加一空白行
sed -n '5~5p' # 只打印行号为5的倍数
seq 1 30|sed '5~5s/.*/a/' # 倍数行执行替换
sed -n '3,${p;n;n;n;n;n;n;}' # 从第3行开始,每7行显示一次
sed -n 'h;n;G;p' # 奇偶调换
seq 1 10|sed '1!G;h;$!d' # 倒叙排列
ls -l|sed -n '/^.rwx.*/p' # 查找属主权限为7的文件
sed = filename | sed 'N;s/\n/\t/' # 为文件中的每一行进行编号(简单的左对齐方式)
sed 's/^[ \t]*//' # 将每一行前导的"空白字符"(空格,制表符)删除,使之左对齐
sed 's/^[ \t]*//;s/[ \t]*$//' # 将每一行中的前导和拖尾的空白字符删除
sed '/{abc,def\}\/\[111,222]/s/^/00000/' # 匹配需要转行的字符: } / [
echo abcd\\nabcde |sed 's/\\n/@/g' |tr '@' '\n' # 将换行符转换为换行
cat tmp|awk '{print $1}'|sort -n|sed -n '$p' # 取一列最大值
sed -n '{s/^[^\/]*//;s/\:.*//;p}' /etc/passwd # 取用户家目录(匹配不为/的字符和匹配:到结尾的字符全部删除)
sed = filename | sed 'N;s/^/ /; s/ *\(.\{6,\}\)\n/\1 /' # 对文件中的所有行编号(行号在左,文字右端对齐)
/sbin/ifconfig |sed 's/.*inet addr:\(.*\) Bca.*/\1/g' |sed -n '/eth/{n;p}' # 取所有I
$ echo this is an example | sed 's/\w\+/[&]/g' #正则表达式 \w\+ 匹配每一个单词,然后我们用 [&] 替换它
[this] [is] [an] [example]
$ echo seven EIGHT | sed 's/\([a-z]\+\) \([A-Z]\+\)/\2 \1/' #正则将位置进行调换 \1第一个子串 \2第二个子串
EIGHT seven
类似如下:
$ echo hujianli shell | awk '{print $2,$1}'
shell hujianli
# 组合多个表达式
$ echo abc|sed 's/a/A/'|sed 's/c/C/'
AbC
$ echo abc|sed 's/a/A/;s/c/C/'
AbC
$ echo abc|sed -e's/a/A/' -e 's/c/C/'
AbC
# 引用
$ text=hujianli
$ echo hujianli hello world |sed "s/${text}/HJL/"
HJL hello world
3.8.5. 修改keepalive配置剔除后端服务器¶
sed -i '/real_server.*10.0.1.158.*8888/,+8 s/^/#/' keepalived.conf
sed -i '/real_server.*10.0.1.158.*8888/,+8 s/^#//' keepalived.conf
3.8.6. sed练习¶
修改源文件本身则需要使用“-i”参数
3.8.7. 使用sed修改文件流的方式¶
使用-e 参数和分号连接多编辑命令
[root@localhost ~]# cat sed.txt
this is line 1,this is First line
this is line 2,the Second line,Empty line followed
this is line 4 ,this is Third line
this is line 5 this is fifth line
[root@localhost ~]# sed -e 's/this/That/g' -e 's/line/LINE/g' sed.txt
That is LINE 1,That is First LINE
That is LINE 2,the Second LINE,Empty LINE followed
That is LINE 4 ,That is Third LINE
That is LINE 5 That is fifth LINE
[root@localhost ~]# sed 's/this/That/g;s/line/LINE/g' sed.txt
That is LINE 1,That is First LINE
That is LINE 2,the Second LINE,Empty LINE followed
That is LINE 4 ,That is Third LINE
That is LINE 5 That is fifth LINE
删除¶
[root@localhost ~]# sed '1d' sed.txt
this is line 2,the Second line,Empty line followed
this is line 4 ,this is Third line
this is line 5 this is fifth line
将删除后的内容重定向到sed2.txt中¶
[root@localhost ~]# sed '1d' sed.txt > sed2.txt
[root@localhost ~]# cat sed2.txt
this is line 2,the Second line,Empty line followed
this is line 4 ,this is Third line
this is line 5 this is fifth line
直接删除文件中的第1行¶
[root@localhost ~]# sed -i '1d' sed.txt
[root@localhost ~]# cat sed.txt
this is line 2,the Second line,Empty line followed
this is line 4 ,this is Third line
this is line 5 this is fifth line
删除1-3行的内容¶
[root@localhost ~]# cat sed1.txt
this is line 1,this is First line
this is line 2,the Second line,Empty line followed
this is line 4 ,this is Third line
this is line 5 this is fifth line
[root@localhost ~]# sed '1,3d' sed1.txt
this is line 5 this is fifth line
清空整个文件,1~最后一行¶
[root@localhost ~]# sed '1,$d' sed.txt
删除最后1行的内容¶
[root@localhost ~]# cat sed.txt
this is line 2,the Second line,Empty line followed
this is line 4 ,this is Third line
this is line 5 this is fifth line
[root@localhost ~]# sed '$d' sed.txt
this is line 2,the Second line,Empty line followed
this is line 4 ,this is Third line
删除包含Empty的行¶
[root@localhost ~]# sed '/Empty/d' sed1.txt
this is line 1,this is First line
this is line 4 ,this is Third line
this is line 5 this is fifth line
删除空行¶
[root@localhost ~]# sed '/^$/d' sed.txt
删除包含1以外的其它行¶
[root@localhost ~]# sed '1!d' sed1.txt
this is line 1,this is First line
3.8.8. 查找和替换¶
替换匹配到line的行,只替换匹配到的第1次¶
[root@localhost ~]# sed 's/line/LINE/' sed.txt
this is LINE 1,this is First line
this is LINE 2,the Second line,Empty line followed
this is LINE 4 ,this is Third line
this is LINE 5 this is fifth line
替换匹配到line的行,只替换匹配到的第2次¶
[root@localhost ~]# sed 's/line/LINE/2' sed.txt
this is line 1,this is First LINE
this is line 2,the Second LINE,Empty line followed
this is line 4 ,this is Third LINE
this is line 5 this is fifth LINE
所有匹配值的替换¶
[root@localhost ~]# sed 's/line/LINE/g' sed.txt
this is LINE 1,this is First LINE
this is LINE 2,the Second LINE,Empty LINE followed
this is LINE 4 ,this is Third LINE
this is LINE 5 this is fifth LINE
替换开头以this的行¶
[root@localhost ~]# sed 's/^this/that/' sed.txt
that is line 1,this is First line
that is line 2,the Second line,Empty line followed
that is line 4 ,this is Third line
that is line 5 this is fifth line
3.8.9. 字符转换¶
使用y命令可进行字符转换,其作用为将一系列字符逐个地变换为另外一系列字符,
[root@localhost ~]# sed 'y/1245/ABCD/' sed.txt
this is line A,this is First line
this is line B,the Second line,Empty line followed
this is line C ,this is Third line
this is line D this is fifth line
3.8.10. 插入文本¶
在第2行后添加一行空行¶
[root@localhost ~]# sed '2G' sed.txt
this is line 1,this is First line
this is line 2,the Second line,Empty line followed
this is line 4 ,this is Third line
this is line 5 this is fifth line
若是一行里面有shui这个单词,那么在他后面会添加一个空行¶
sed "/shui/G" tmp
若是一行里面有shui这个单词,那么在他前后各添加一个空行¶
sed "/shui/{x;p;x;G}" tmp
若是一行里面有shui这个单词,那么在他前面添加一个空行¶
sed "/shui/{x;p;x;}" tmp
在第一行前面添加空行,想在第几行,号令中的1就改成几¶
sed '1{x;p;x;}' tmp
在第二行前插入文本¶
[root@localhost ~]# sed '2 i Insert' sed.txt
this is line 1,this is First line
Insert
this is line 2,the Second line,Empty line followed
this is line 4 ,this is Third line
this is line 5 this is fifth line
在第二行后插入文本¶
[root@localhost ~]# sed '2 a Insert' sed.txt
this is line 1,this is First line
this is line 2,the Second line,Empty line followed
Insert
this is line 4 ,this is Third line
this is line 5 this is fifth line
在匹配行的前面插入1行文本¶
[root@localhost ~]# sed '/Second/i\Insert' sed.txt
this is line 1,this is First line
Insert
this is line 2,the Second line,Empty line followed
this is line 4 ,this is Third line
this is line 5 this is fifth line
3.8.11. 读入文本¶
将/etc/passwd的内容读入到sed.txt的空行之后¶
[root@localhost ~]# sed '/^$/r /etc/passwd' sed.txt
this is line 1,this is First line
this is line 2,the Second line,Empty line followed
this is line 4 ,this is Third line
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
libstoragemgmt:x:998:996:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
amandabackup:x:33:6:Amanda user:/var/lib/amanda:/bin/bash
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
colord:x:997:994:User for colord:/var/lib/colord:/sbin/nologin
pcp:x:996:993:Performance Co-Pilot:/var/lib/pcp:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:995:992::/var/lib/chrony:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
oprofile:x:16:16:Special user account to be used by OProfile:/var/lib/oprofile:/sbin/nologin
hujianli:x:1000:1000:hujianli:/home/hujianli:/bin/bash
nginx:x:994:991:Nginx web server:/var/lib/nginx:/sbin/nologin
mysql:x:1001:1001::/home/mysql:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
ixdba:x:1002:1002::/home/ixdba:/bin/bash
ixdba1:x:1003:1003::/ixdba/ixdba1:/bin/bash
ixdba2:x:1004:1004::/ixdba/ixdba2:/sbin/nologin
this is line 5 this is fifth line
3.8.12. 打印¶
打印第1行¶
[root@localhost ~]# sed -n '1p' sed.txt
this is line 1,this is First line
只打印匹配到的行¶
[root@localhost ~]# sed -n 's/the/THE/p' sed.txt
this is line 2,THE Second line,Empty line followed
3.8.13. 写文件¶
## 将匹配打印到的内容输出到 output文件中
[root@localhost ~]# sed -n '1,2 w output' sed.txt
[root@localhost ~]# cat output
this is line 1,this is First line
this is line 2,the Second line,Empty line followed
3.8.14. sed 脚本¶
编写一个sed脚本¶
[root@localhost ~]# cat sed.rules
s/this/THAT/g
/^$/d
加载sed脚本¶
[root@localhost ~]# sed -f sed.rules sed.txt
THAT is line 1,THAT is First line
THAT is line 2,the Second line,Empty line followed
THAT is line 4 ,THAT is Third line
THAT is line 5 THAT is fifth line
3.8.15. 高级替换¶
替换空白行后的一行的内容¶
[root@localhost ~]# sed '/^$/{n;s/line/LINE/g}' sed.txt
this is line 1,this is First line
this is line 2,the Second line,Empty line followed
this is LINE 4 ,this is Third LINE
this is line 5 this is fifth line