基本用法:
sed是流编辑器,stream editor可以实现对文件的增删改查
1.增
a
追加内容
i
插入内容
例如:
sed -i '2a 123' test.log 追加123到test.log的第二行
sed -i '2a 123\n321' test.log 追加两行内容到第二行后,\n是换行符
sed -i '$a 123' test.log 文件末尾追加
知识点:指定执行的地址范围
2.删
d
删除
例:
sed -i '2,3d' test.log 删除2 3 行
sed -i '1+2d' test.log 删除123行
sed '/oldboy/d' persion.txt 删除包含oldboy的行并且打印
3.改
c
change 用新行取代旧行
sed -i '2c 888' test.log 将test.log的第二行替换成888
3.2文本替换
s:单独使用 将每一行中的第一处匹配的字符串进行替换 ==> sed命令
g:每一行进行全部替换 sed命令s的替换标志之一,==>并非是sed命令
-i:修改文件内容 ==> sed软件的选项
sed软件替换模型
sed -i 's/■/▲/g' 123.log #和/都是定界符,只要是三个相同即可。
sed -i 's#■#▲#g' 123.log
特点:
a.两边是引号,引号里面分别为s和g,中间是一个三个一样的字符,可以使是/
或者#
作为定界符,定界符可以使任意符号,如:|
等,单当替换内容包含定界符时,需要转义。
b.定界符/
或#
,第一个和第二个之间的就是被替换的内容,第二个和第三个之间就是替换后的内容
c.s#■#▲#g
中,方块的内容可以使用正则表达式,但是三角的内容不可以使用正则,也就是内容必须是具体的。
d.默认sed软件是对模式空间(内存中的数据)操作,而-i
选项会更改磁盘上的文件内容。
sed -i 's#foorbar#foo#g' /tmp/foobar.txt
第一个s
是替换,中间三个#
是分隔符,也可使用/
、%
,理论上任意字符都可以,最后一个g
是全局替换
-i
是修改文件内容,否则知识输出改变文件不变。
sed下对包含空格或者 制表符的文本进行替换(由于disable前面有tab制表符,使用\t进行转义,空格就直接用\
进行转义即可)
sed -i 's/\tdisable\ =\ yes/\tdisable\ =\ no\ /g' /etc/xinetd.d/rsync 注意空格可以不是用转移字符,也就是's#\tdisable = yes#\tdisbale = no#g'
sed 在指定行下插入新内容
sed -i '2i888' line.txt 在指定第二行插入888,原来的第二行变为第第三行,可以理解在第二行上面插入 参数:2i 2为行数
sed -i '2a999' line.txt 在指定第二行插入999,原来第二行不变,可以理解在第二行下面插入 参数:2a 2为行数
sed在指定行修改内容,也就是精确修改配置
sed -i '3s#foobar#barfoo#g' /tmp/foobar.log 修改第三行所有foobar为barfoo
sed -i '3s#0#9#' /tmp/123.txt 修改第三行的第一个0为9
关于单双引号的说明
在bash环境中使用单引号
''
,单引号中的内容所见即所得
使用双引号
""
,双引号中的部分特殊字符会起到他们的作用,这些特殊字符有:$
\
!
但是当使用
eval
后面接单引号时,此时的单引号和双引号的作用一样,特殊字符会起作用。
3.2.1分组替换( )和\1的使用说明
sed软件的( )的功能可以记住正则表达式的一部分内容,其中,\1位第一个记住的模式,即记住的第一个小括号的内容,\2为第二个记住的模式,以此类推,sed软件最多可以记住9个
例如:echo I am a oldboy teacher.
,如果想保留这一行的单词oldboy,删除剩余部分,则使用圆括号标记想保留的内容
如果想不使用反斜线进行转义,可以使用sed -r
命令来转义
echo I am a oldboy teacher. | sed 's#^.*am a \([a-z].*\) tea.*$#\1#g'
下面解释用□代替空格
1.
^.*□
这句的意思是,以任意字符开头到am□
为止,匹配文件中的I am□
字符串;
.\([a-z]\)
□ 这句的外壳就是括号\(\)
,里面的[a-z]
标志匹配26个小写字母的任何一个,[a-z].*
合起来就是匹配任意多个字符,本体来说就是匹配oldboy
字符串,由于oldboy
字符串时需 要保留的,因此用括号括起来进行匹配,后面用\1
来取这个oldboy
字符串。
3.□tea.*$
表示以空格tea
其实,任意字符结尾,就是匹配oldboy
字符串后,紧接着的字符串□teacher.
4.后面被替换的内容\1
就是去前面括号的内容,即oldboy
.()
是扩展表达式的元字符,sed软件默认识别基本正则表达式,想要使用扩展正则需要使用\
进行转义,即\(\)
。sed使用 -r
选项则可以识别正则表达式,此时再使用\( \)
会出错。
3.2.2 关于&
符号的使用
特殊符号&
,用来代替替换的内容
企业应用场景模拟:
[root@centostest test]# touch stu_12999_{1..5}_finished.jpg 创建文件
查看目录现有文件
[root@centostest test]# ls -l
总用量 0
-rw-r--r--. 1 root root 0 11月 17 16:18 stu_12999_1_finished.jpg
-rw-r--r--. 1 root root 0 11月 17 16:18 stu_12999_2_finished.jpg
-rw-r--r--. 1 root root 0 11月 17 16:18 stu_12999_3_finished.jpg
-rw-r--r--. 1 root root 0 11月 17 16:18 stu_12999_4_finished.jpg
-rw-r--r--. 1 root root 0 11月 17 16:18 stu_12999_5_finished.jpg
[root@centostest test]# ls *jpg | sed -r 's#(^.*)_finished.*#mv & \1.jpg#g' | bash
命令解析:首先是( )
和\1
的对应,命令中小括号里面的意思是匹配任意字符,第一对儿井号之间的内容的意思是任意开头以_finished.
结尾的内容,第二对井号里面的内容意思就是,mv 重命名,&
代表第一对井号里面匹配到的内容, \1
代表第一对井号里面小括号的内容,也就是stu_12999_1、stu_12999_2...这些内容,最后管道后面的bash是让命令运行,而不是显示结果,注意bash
在这里的用法
3.2.3 可以使用rename
命令来简化上面的操作,rename
命令是一个专业的重命名工具。
命令解析:rename
“匹配内容” “更改后的内容” 文件名
rename from to file
rename "_finished" "" *
rename "jpg" "png" *
from代表要替换或者要处理字符,一般是文件的一部分,或者是文件的扩展名
to 把前面from代表的内容替换为to代表的内容,即重命名处理后的结果。
3.2.4 basename重命名
touch tea_12888_{1..9}_finished.jpg 创建9个文件
[root@centostest test]# basename /tmp/test/tea_12888_1_finished.jpg .jpg
tea_12888_1_finished
4.查
p
输出指定内容,但默认会输出2次匹配的结果,因此使用n
取消默认输出
-n
取消默认输出,p
打印,下面就是打印seq.txt文件的第20到底30行
sed -n '20,30p' seq.txt
打印最后一行
sed -n '$p' seq.txt
打印第一行
sed -n '1p' seq.txt
打印包含指定字符串的行
sed -n '/CTO/p' persion.txt 打印包含CTO的行
sed -n '/CTO/,/CFO/p' persion.txt 打印包含从CTO到CFO字符换的行
特殊情况
sed -n '/feixue/,2p' persion.txt 打印从feixue这行开始到第二行,但是如果不符合这个条件,还是会打印出feixue这行
混合查询
sed -n '2,/CFO/p' persion.txt 打印从第二行开始,直到包含CFO这样字符串的之间的行
模拟题
1.将/tmp/oldboy/test目录下的所有后缀为sh的文件里包含oldboy的字符串替换为oldgirl
find /tmp/oldboy/test/ -type f -name "*.sh" | xargs cat
配合find来解决,其中xargs
用作替换工具,读取输入数据重新格式化后输出,如果不使用xargs,是无法直接使用cat读取的。
find /tmp/oldboy/test -type f -name "*.sh" | xargs sed -i 's#oldboy#oldgirl#g'
之后再次查看内容
[root@nmnsr ~]# find /tmp/oldboy/test -type f -name "*.sh" |xargs cat
oldgirl
oldgirl
oldgirl
也可以使用如下方式
sed -i 's#oldboy#oldgirl#g'`find /tmp/oldboy/test -type f -name "*.sh"`
说明:` `里面的优先执行,取得执行结果。
2.批量更改文件名
ls *.png.jpg | sed -r 's#(.*).png.jpg#mv & \1.jpg#' |bash
网友评论