本文共 7784 字,大约阅读时间需要 25 分钟。
Sed简介:
sed是stream editor的缩写,是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,只是对存放在缓冲区里的行做处理,除非使用重定向存储输出。
语法是:sed [options] ‘{command}’ [filename]
定址:
通过定址来定位所需编辑的行,该地址用数字构成,用逗号分隔的两个行数表示以这两行为起止的行的范围(包括行数表示的那两行)。如1,3表示1,2,3行,美元符号($)表示最后一行。范围可以通过数据,正则表达式或者二者结合的方式确定 。
字符参数:
/sed/ 匹配所有sed的行
^ 行首定位符 /^sed/匹配所有以sed开头的行
$ 行尾定位符 /sed$/匹配所有以sed结尾的行
. 匹配除换行符以外的单个字符 /s.d/匹配s后接一个任意字符,然后是d
* 匹配零个或多个前面出现的字符 /*sed/匹配所有模板是一个或多个字符后紧跟sed的行
[] 匹配指定字符组内的任一字符 /[Ss]ed/匹配sed和Sed
[^] 匹配不在指定字符组内的任一字符 /[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头紧跟ed的行
\(..\) 保存已匹配的字符 s/\(love\)able/\1rs,loveable被替换成lovers
\< 词首定位符 /\<love/匹配包含以love开头的单词的行
\> 词尾定位符 /love\>/匹配包含以love结尾的单词的行
x\{m\} 连续m个x /0\{5\}/匹配包含5个o的行
x{m,\} 至少m个x /o\{5,\}/匹配至少有5个o的行
x\{m,n\} 至少m个,但不超过n个x /o\{5,10\}/匹配5--10个o的行
[[:space:]]表示空格或者tab的集合
option:
-n 使用安静的模式,只有经过sed处理的那一行才会被列出来,否则要处理的那行会出现两次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [root@justin home] # cat sed.txt 1 2 2 2 3 4 5 2 2 2 2 3 4 5 3 2 2 2 3 4 5 4 3 4 4 9 2 2 [root@justin home] # sed '/^3/p' sed.txt 1 2 2 2 3 4 5 2 2 2 2 3 4 5 3 2 2 2 3 4 5 3 2 2 2 3 4 5 4 3 4 4 9 2 2 [root@justin home] # sed -n '/^3/p' sed.txt 3 2 2 2 3 4 5 [root@justin home] # |
匹配以3开头的行并打印出来,p表示打印匹配的行,
1 2 3 4 5 6 7 | [root@justin home] # sed -n '2p' sed.txt 2 2 2 2 3 4 5 [root@justin home] # sed -n '2,$p' sed.txt 2 2 2 2 3 4 5 3 2 2 2 3 4 5 4 3 4 4 9 2 2 [root@justin home] # |
显示指定行内容
-e 允许多个编辑同时进行,也可以用分号隔开。一般用”;”更为简洁。
1 2 3 4 5 6 7 | [root@justin home] # sed -e '1,2d' -e '3s/2/8/g' sed.txt 3 8 8 8 3 4 5 4 3 4 4 9 2 2 [root@justin home] # sed '1,2d;3s/2/8/g' sed.txt 3 8 8 8 3 4 5 4 3 4 4 9 2 2 [root@justin home] # |
r filename 从文件中读取
1 2 3 4 5 6 7 8 9 10 11 12 13 | [root@justin home] # cat sed1.txt a b c d e f [root@justin home] # sed '/^2/r sed1.txt' sed.txt 1 2 2 2 3 4 5 2 2 2 2 3 4 5 a b c d e f 3 2 2 2 3 4 5 4 3 4 4 9 2 2 [root@justin home] # |
读取sed1.txt文件,并显示在sed.txt中匹配2开头行之后
w filename 写入数据
1 2 3 4 5 6 7 8 | [root@justin home] # sed '/^2/w sed1.txt' sed.txt 1 2 2 2 3 4 5 2 2 2 2 3 4 5 3 2 2 2 3 4 5 4 3 4 4 9 2 2 [root@justin home] # cat sed1.txt 2 2 2 2 3 4 5 [root@justin home] # |
将sed.txt中匹配2开头的行,并写入到sed1.txt中
-i 直接修改文件内容,而不屏幕输出
将nrpe.cfg里面第221行中的check_hda1全部替换成/check_disk_root,/dev/hda1全部替换成/dev/sda3
1 | sed -i '221s/check_hda1/check_disk_root/g;221s?/dev/hda1?/dev/sda3?g' /usr/local/nagios/etc/nrpe .cfg |
sed当中使用变量替换,sed命令使用双引号的情况下,使用$var直接引用
1 2 3 4 | #!/bin/bash ROOTPATH=` df -Th| grep /$| awk '{print $1}' ` sed -i "221s?/dev/sda3?$ROOTPATH?g" /usr/local/nagios/etc/nrpe .cfg #sed -i '221s?/dev/sda3?'"$ROOTPATH"'?g' /usr/local/nagios/etc/nrpe.cfg |
第二条命令$ROOTPATH里面的是双引号,外面的是单引号
-f 直接sed的动作写在一个文件中,-f filename则可以执行filename内的sed动作
常用command:
i 在当前行之前插入文本, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
1 2 3 4 5 6 7 8 | [root@justin home] # sed '/^1/i adfdf\ndddd' sed.txt adfdf dddd 1 2 2 2 3 4 5 2 2 2 2 3 4 5 3 2 2 2 3 4 5 4 3 4 4 9 2 2 [root@justin home] # |
在匹配行前加入一行
1 2 3 4 5 6 7 8 | [root@localhost ~] # sed -i '/tcp --dport 80 -j ACCEPT/i\-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT' /etc/sysconfig/iptables [root@localhost ~] # cat /etc/sysconfig/iptables ... -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT .... [root@localhost ~] # |
sed -i '/tcp --dport 80 -j ACCEPT/i\-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT' /etc/sysconfig/iptables
i\ 中的\可以替换成空格
sed -i '/tcp --dport 80 -j ACCEPT/i -A INPUT -m state --state NEW -m tcp -p tcp --dport 8090 -j ACCEPT' /etc/sysconfig/iptables
a 在当前行下一行加入一行文本,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | [root@justin home] # sed '1a test' sed.txt 1 2 2 2 3 4 5 test 2 2 2 2 3 4 5 3 2 2 2 3 4 5 4 3 4 4 9 2 2 [root@justin home] # sed '1,3a test' sed.txt 1 2 2 2 3 4 5 test 2 2 2 2 3 4 5 test 3 2 2 2 3 4 5 test 4 3 4 4 9 2 2 [root@justin home] # sed '1a test\ntest1' sed.txt 1 2 2 2 3 4 5 test test1 2 2 2 2 3 4 5 3 2 2 2 3 4 5 4 3 4 4 9 2 2 [root@justin home] # sed '1a test\ntest1\ntest2' sed.txt 1 2 2 2 3 4 5 test test1 test2 2 2 2 2 3 4 5 3 2 2 2 3 4 5 4 3 4 4 9 2 2 [root@localhost ~] # |
在匹配行后加入一行
1 2 3 4 5 6 7 8 9 | [root@localhost ~] # sed -i '/tcp --dport 80 -j ACCEPT/a\-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT' /etc/sysconfig/iptables [root@localhost ~] # cat /etc/sysconfig/iptables ... -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 5901 -j ACCEPT ... [root@localhost ~] # |
在最后一行加入一行
1 | [root@localhost ~] # sed -i '$a\TMOUT=1800' /etc/profile |
c 取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
1 2 3 4 5 6 7 8 9 | [root@justin home] # sed '1c Hi' sed.txt Hi 2 2 2 2 3 4 5 3 2 2 2 3 4 5 4 3 4 4 9 2 2 [root@justin home] # sed '1,3c Hi' sed.txt Hi 4 3 4 4 9 2 2 [root@justin home] # |
s 替换,格式:sed 's/要替换的字符串/新的字符串/g' (要替换的字符串可以用正则表达式),三根斜线中间是替换的样式,命令中的三根斜线分隔符可以换成别的符号,例如换成问号”?”:sed 's?原字符串?替换字符串?',这里的替换用法类似前面提到的vim里的替换
替换样式可以多个在同一条命令中执行,用分号”;”分隔,例如:
sed 's/^/添加的头部&/g;s/$/&添加的尾部/g' //同时执行两个替换规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | [root@justin home] # sed -n '2s/2/3/p' sed.txt ;第二行的第一个2替换为3,并打印出来 3 2 2 2 3 4 5 [root@justin home] # sed -n '2s/2/3/gp' sed.txt ;第二行的2全部替换为3,并打印出来,g为全部替换 3 3 3 3 3 4 5 [root@justin home] # sed -n 's/2/3/gp' sed.txt ;将所有行的2替换为3 1 3 3 3 3 4 5 3 3 3 3 3 4 5 3 3 3 3 3 4 5 4 3 4 4 9 3 3 [root@justin home] # sed -n '1s/2/3/p;3s/2/7/gp' sed.txt ;第一行的第一个2替换为3,第三行2全部替换为7 1 3 2 2 3 4 5 3 7 7 7 3 4 5 [root@justin home] # sed -n '2,3s/3/9/p' sed1.txt ;第2、3行的第一个3替换为9 9 1 3 2 4 3 6 7 9 1 3 2 3 4 5 6 [root@justin home] # sed -i '2s?^?# chkconfig: 2345 10 90\n# description:Tomcat service\nCATALINA_HOME=/app/apache-tomcat-7.0.61\nJAVA_HOME=/app/jdk1.7.0_79?' /etc/init.d/tomcat |
s前面的数字表示要匹配的行号,不写默认为全部匹配,g表示全部,如果没有g标记,则只有每行第一个匹配的,“\n”表示换行
1 2 3 | [root@justin home] # sed -n '2s/2/3/3p' sed.txt 2 2 3 2 3 4 5 [root@justin home] # |
&符号表示替换换字符串中被找到的部份
$ sed 's/^192.168.0.1/&localhost/' example
所有以192.168.0.1开头的行都会被替换成它自已加 localhost,变成192.168.0.1localhost。
p前面的数字3为要把第几个2匹配为3
1 2 3 | [root@justin home] # sed -n '/9/s/3/5/gp' sed.txt 4 5 4 4 9 2 2 [root@justin home] # |
匹配有9的行,然后把改行的3替换为5
sed ‘s/\(.*\)old/\1new/’ filename 替换每行的最后1个”old”为”new”
1 2 3 4 5 6 7 8 9 | [root@justin home] # sed -n '/9/!s/3/5/gp' sed.txt 1 2 2 2 5 4 5 2 2 2 2 5 4 5 5 2 2 2 5 4 5 [root@justin home] # sed -n '/^2/!p' sed.txt 1 2 2 2 3 4 5 3 2 2 2 3 4 5 4 3 4 4 9 2 2 [root@justin home] # |
感叹号表示不匹配感叹号之前的条件
d 删除行
1 2 3 | [root@justin home] # sed '/5$/ d' sed.txt 4 3 4 4 9 2 2 [root@justin home] # |
删除末尾为5的行
1 | [root@justin ~] # cat /etc/samba/smb.conf |egrep -v '#|;'|sed '/^[[:space:]]*$/d' |
1 | [root@justin home] # cat /etc/samba/smb.conf |sed '/^*$/d'|egrep -v '#|;' |
删除空白行,[[:space:]]表示空格或者tab的集合,[[:space:]]后面跟着一个*,表示匹配0个或多个空格或者tab。[[:space:]]可以用/s表示
1 2 3 4 5 6 7 8 | [root@justin home] # sed '1d' sed.txt 2 2 2 2 3 4 5 3 2 2 2 3 4 5 4 3 4 4 9 2 2 [root@justin home] # sed '2,3d' sed.txt 1 2 2 2 3 4 5 4 3 4 4 9 2 2 [root@justin home] # |
删除指定行
w 将匹配的输一局写入其他文件
1 2 3 4 5 6 | [root@justin home] # touch sed2.txt [root@justin home] # sed -n '2,3 w sed2.txt' sed.txt [root@justin home] # cat sed2.txt 2 2 2 2 3 4 5 3 2 2 2 3 4 5 [root@justin home] # |
p 打印,将某个选择的资料打印出来。通常 p 会与参数 sed -n 一起运作
Tips:
行后增加一行空行:[root@justin home]# sed G sed.txt
行后增加两行空行:[root@justin home]# sed 'G;G' sed.txt
倒置所有行,第一行成为最后一行[root@justin home]# sed -n ’1!G;h;$p’ filename或是sed ’1!G;h;$!d’ filename
filename每两行合并成一行[root@justin home]# sed ‘$!N;s/\n/ /’ filename
删除文件中相邻的重复行[root@justin home]# sed ‘$!N; /^\(.*\)\n\1$/!P; D’
本文转自 justin_peng 51CTO博客,原文链接:http://blog.51cto.com/ityunwei2017/1335907,如需转载请自行联系原作者