sed不多介绍,总之sed,awk,grep是文本操作的三大利器。非常有必要掌握,之前有一篇文章:linux下的sed命令详解-04007技术笔记 也有相关介绍 。sed是数据流编辑器,操作纯ascii码的文本。是一个行操作编辑器(vi属于全屏编辑器)
模式空间:从文件中取出内容存放至模式空间(不编辑原文件)。sed处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
一、按行取内容:
可指定行号,或者指定行号范围,$代表最后一行。也可以使用+表示向后再取几行。
示例:sed -n 1,3p filename
其中 -n:表示静默模式,不再显示模式空间的内容。否则会在你要的结果后面加上整个模式空间的内容。
另外 -i:则直接修改原文件
p命令:表示只显示符合条件的行。
[root@123 ~]# sed 2p a.txt
1=春天
2=春天
2=春天 #此行即为匹配到的行
helloworld
3=秋天
4=冬天
yes it is me
3= 夏天
5=秋天1222
test
6=秋天2
[root@123 ~]# sed -n 2p a.txt
2=春天
[root@123 ~]# sed -n '$p' a.txt #使用$表示最后一行,但此时需要加上引号
6=秋天2
[root@123 ~]# sed -n '2,+2p' a.txt #取第2行,同时向后再取2行
2=春天
helloworld
3=秋天
[root@123 ~]# tail -3 a.txt | sed -n '1,2p' #取到数第2和第3行。这时需要结合tail操作。
1=春天
2=春天
3=秋天
4helloworld
5=冬天
6yes it is me
7= 夏天
8=秋天1222
9test
10=秋天2
[root@123 ~]# tail -n +5 a.txt| head -n 2 #也可以使用tail 和head结合,从第5行开始取2行。
5=冬天
6yes it is me
[root@123 ~]# head -n 6 a.txt | tail -n 2 #显示第5到第6行的数据
5=冬天
6yes it is me
[root@123 ~]# sed -n '2p;6,7p' a.txt #取分散的行,也可以使用括号括起来sed -n '{2p;6,7p}' a.txt
2=春天
6yes it is me
7= 夏天
其它可以执行的命令(即上面的p位置的其它命令)
d命令:删除符合条件的行。sed '1,34d' c.txt删除1-34行,
a命令:在指定的行后面加上一个新行。追加方式 \string: 两行sed '/^a/a\aaaaaaaaa\nbbbbbbb' c.txt
i命令:在指定的行前中加上新行。
c取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
r命令:r FILE:将指定文件和内容添加至符合条件的行处。sed '2r a.txt' c.txt在第2行追加一个文件
w命令:将指定范围的行另存至文件:sed '/^root/w a.txt' c.txt
命令示例如下:
[root@123 ~]# cat c.txt
1=春天
2=春天
3=秋天
4helloworld
[root@123 ~]# sed /1=/d c.txt
2=春天
3=秋天
4helloworld
[root@123 ~]# sed /2=/d c.txt
1=春天
3=秋天
4helloworld
[root@123 ~]# sed '/2=/a\this is a' c.txt
1=春天
2=春天
this is a
3=秋天
4helloworld
[root@123 ~]# sed '/2=/i\this is a' c.txt
1=春天
this is a
2=春天
3=秋天
4helloworld
[root@123 ~]# sed '/2=/c\this is a' c.txt
1=春天
this is a
3=秋天
4helloworld
[root@123 ~]# sed '/2=/r b.txt' c.txt
1=春天
2=春天
this is from b.txt
3=秋天
4helloworld
[root@123 ~]# sed '/2=/w z.txt' c.txt
1=春天
2=春天
3=秋天
4helloworld
[root@123 ~]# cat z.txt
2=春天
[root@123 ~]#
二、模式匹配查找
使用模式的格式:/kermit/ 示例 sed '/222/d' a.txt即表示查找到包括222的行,并且执行删除(d命令)
[root@123 ~]# cat a.txt
1=春天
2=春天
3=秋天
4helloworld
5=冬天
6yes it is me
7= 夏天
8=秋天1222
9test
10=秋天2
[root@123 ~]# sed -n '/2=/p' a.txt
2=春天
[root@123 ~]# sed -n '/2=/d' a.txt #此时使用-n就没法查看效果,如下
[root@123 ~]# sed '/2=/d' a.txt
1=春天
3=秋天
4helloworld
5=冬天
6yes it is me
7= 夏天
8=秋天1222
9test
10=秋天2
[root@123 ~]# sed -n '/^1/p' a.txt #查看以1开始的内容
1=春天
10=秋天2
[root@123 ~]# sed -n '/2$/p' a.txt #查看以2结尾的内容
8=秋天1222
10=秋天2
[root@123 ~]# sed -n '/ /p' a.txt #查看包含空格字符的内容
6yes it is me
7= 夏天
模式匹配操作时,同样能执行上面的d,p,a,i,c,r,w命令。并且模式匹配还支持范围,例如/pattern1/,/pattern2/ 表示第一次被p1匹配到的行到第一次p2匹配行。
[root@123 ~]# sed -n '/2=/,/3=/p' c.txt
2=春天
3=秋天
[root@123 ~]# nl c.txt | sed '/world$/i\ add yes;'
1 1=春天
2 2=春天
3 3=秋天
add yes;
4 4helloworld
三、sed的替换、引用、以及引用,后向引用
替换命令:s,实际替换命令s和上面的这些d/p/a/i/c/w/r一样,是个普通的命令,但是s命令使用的更广泛,所以单独拿出来列一个。
s命令格式:/pattern/string/修饰符: 查找并替换。sed 's/hello/hehe/' c.txt 即表示替换hello成hehe.此处的修饰符为空,即默认只替换每行第一次匹配的。
[root@123 ~]# cat c.txt
1=春天
2=第2行world
3=春天
4=秋天
5helloworld,it is a newworld
[root@123 ~]# sed 's/world/yes/' c.txt #未使用修饰符,每行只替换第一次。
1=春天
2=第2行yes
3=春天
4=秋天
5helloyes,it is a newworld
[root@123 ~]# sed 's/world/yes/g' c.txt #此处使用了修饰符,第5行也替换了。
1=春天
2=第2行yes
3=春天
4=秋天
5helloyes,it is a newyes
关于修饰符:使用g表示全局替换(像上面就会把第5行后面的也替换),i忽略大小写。
关于替换s:还有个重要的东西,那就是上面我们都是使用的斜线/作为分隔符号,实际这个分隔符号是可以更换的;这个特别适合在对路径进行替换,这时路径中的斜线就不需要转义。如下:
[root@123 ~]# sed -n 's#world#yes#g;p' c.txt
1=春天
2=第2行yes
3=春天
4=秋天
5helloyes,it is a newyes
[root@123 ~]# echo '/usr/local/localpass/www/baidu.com/' | sed 's/\/localpass\/www\//\/www\//g' #如果不更换分隔符号,写起来就很不方便。
/usr/local/www/baidu.com/
[root@123 ~]# echo '/usr/local/localpass/www/baidu.com/' | sed 's#/localpass/www/#/www/#g' #这样替换就不需要转义斜线
/usr/local/www/baidu.com/
关于引用模式:
引用模式,示例:sed 's/wo.ld/ my &/' c.txt 使用&符号可取得前面匹配的内容。
[root@123 ~]# sed 's/wo.ld/ my &/' c.txt
1=春天
2=第2行 my world
3=春天
4=秋天
5hello my world,it is a newworld
[root@123 ~]# sed 's/w..ld/ my &/' c.txt #&就是前面匹配到的world整个字符。
1=春天
2=第2行 my world
3=春天
4=秋天
5hello my world,it is a newworld
[root@123 ~]# sed 's/w*ld/ my &/' c.txt
1=春天
2=第2行wor my ld
3=春天
4=秋天
5hellowor my ld,it is a newworld
后向引用:sed 's/\(r..t\)/\1er/' b.txt; sed 's/r\(..t\)/R\1/' b.txt此时只能用后向引用。
[root@123 ~]# sed 's/\(wo..d\)/ my \1/' c.txt
1=春天
2=第2行 my world
3=春天
4=秋天
5hello my world,it is a newworld
[root@123 ~]# sed 's/\(wo..d\)/ my \1/g' c.txt #在前面使用括号包起来,后面使用\1引用前面的内容。
1=春天
2=第2行 my world
3=春天
4=秋天
5hello my world,it is a new my world
[root@123 ~]# sed 's/hello\(w...d\).*\1/allworld/' c.txt #如此处在匹配时使用了\1表示本行有两个world.所以只替换了第5行内容。
1=春天
2=第2行world
3=春天
4=秋天
5allworld,loveyou
6helloworld,newday,oveyou
除此之外,sed命令还有其它的options选项,不过一般用得较长,能掌握上面的内容就够用了。其它选项和所有元字符集以及所有命令列表如下:
-e:支持多个操作同时进行,-e 命令 -e命令 同时执行多个脚本
-f:把脚本写到文件里,读取出来匹配 sed -f /path/to/script file.将脚本每行读出来应用。
-r:默认-r,表示使用扩展正则表达式。
sed元字符集
^ #匹配行开始,如:/^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结尾的单词的行。
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的行。
sed可用的全部命令如下:
a\ 在当前行下面插入文本。
i\ 在当前行上面插入文本。
c\ 把选定的行改为新的文本。
d 删除,删除选择的行。
D 删除模板块的第一行。
s 替换指定字符
h 拷贝模板块的内容到内存中的缓冲区。
H 追加模板块的内容到内存中的缓冲区。
g 获得内存缓冲区的内容,并替代当前模板块中的文本。
G 获得内存缓冲区的内容,并追加到当前模板块文本的后面。
l 列表不能打印字符的清单。
n 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
N 追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。
p 打印模板块的行。
P(大写) 打印模板块的第一行。
q 退出Sed。
b lable 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾。
r file 从file中读行。
t label if分支,从最后一行开始,条件一旦满足或者T,
t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
T label 错误分支,从最后一行开始,一旦发生错误或者T,
t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
w file 写并追加模板块到file末尾。
W file 写并追加模板块的第一行到file末尾。
! 表示后面的命令对所有没有被选定的行发生作用。
= 打印当前行号码。 # 把注释扩展到下一个换行符以前。