标签:
sed命令是用来处理文本的,且是按行来处理文本,sed处理文本时会将文本内容放置在模式空间中,处理完之后输出模式空间中的文本内容,所以如果你用sed命令处理一个文件,是不会改变文件内容本身的,改变的只是模式空间的临时内容。
sed ‘AddressCommand‘ file ...
Address:可以理解为定位数据,通过一系列的操作,筛选出需要的数据
Command:对选出的数据(行)进行一些什么样的操作
下面分开来说
Address:
1、StartLine,EndLine
例:
1,100 --就是1到100行的意思
$: --最后一行
2、/RegExp/
通过正则表达式来匹配
例:
/^pas/ --以pas开头的行
3、/pattern1/,/pattern2/
第一次被pattern1匹配到行开始,至第一次被pattern2匹配到的行结束,这中间的所有行
4、LineNumber
指定的行
5、StartLine, +N
从startLine开始,向后的N行
Command:
d:删除符合条件的行
p:显示符合条件的行
a \string:在指定的行后面追加新行,内容为string
i \string:在指定的行前面追加新行,内容为string
r FILE: 将指定的文件的内容添加至符合条件的行处
w FILE: 将地址指定的范围内的行另存至指定的文件中;
s/pattern/string/修饰符:查找并替换,默认只替换每行中第一次被模式匹配到的字符串
加修饰符
g: 全局替换
i: 查找时忽略字符大小写
s///: s###, s@@@ --使用s时,不仅可以用/来做分隔符,还可以使用#和@
\(\), \1, \2 --支持后向引用
&: 引用模式匹配到的整个字符串
例:以/etc/fstab文件为例
#
# /etc/fstab
# Created by anaconda on Mon Aug 11 16:27:41 2014
#
# Accessible filesystems, by reference, are maintained under ‘/dev/disk‘
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=e76a7b8d-20c2-4f94-bdd1-f4054a34c206 / ext4 defaults,barrier=0 1 1
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
删除前10行
[root@iZ28g26851kZ ~]# sed ‘1,10d‘ /etc/fstab
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
[root@iZ28g26851kZ ~]#
删除#号开头的行
[root@iZ28g26851kZ ~]# sed ‘/^#/d‘ /etc/fstab
UUID=e76a7b8d-20c2-4f94-bdd1-f4054a34c206 / ext4 defaults,barrier=0 1 1
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
[root@iZ28g26851kZ ~]#
例:显示以#号开头的行
[root@iZ28g26851kZ ~]# sed ‘/^#/p‘ /etc/fstab
#
#
# /etc/fstab
# /etc/fstab
# Created by anaconda on Mon Aug 11 16:27:41 2014
# Created by anaconda on Mon Aug 11 16:27:41 2014
#
#
# Accessible filesystems, by reference, are maintained under ‘/dev/disk‘
# Accessible filesystems, by reference, are maintained under ‘/dev/disk‘
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
#
UUID=e76a7b8d-20c2-4f94-bdd1-f4054a34c206 / ext4 defaults,barrier=0 1 1
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
[root@iZ28g26851kZ ~]#
居然显示了2遍,不但如此,没有被匹配到的行也显示出来了,
为什么呢?
之前有提到过,sed处理文本是先读到模式空间中,处理完在显示出来,之前的删除,sed将模式空间中符合匹配结果的行删除掉,然后将模式空间中剩下的行显示出来这没有问题,但是现在,sed是将匹配到的结果显示出来了,但是同时还要将模式空间中的内容也显示出来,所以就出现了这样的尴尬局面~~
怎么解决呢?
使用-n
命令可以开启静默模式,也就是不会再将模式空间中的内容显示出来,而是只显示匹配到的结果
[root@iZ28g26851kZ ~]# sed -n ‘/^#/p‘ /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Aug 11 16:27:41 2014
#
# Accessible filesystems, by reference, are maintained under ‘/dev/disk‘
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
[root@iZ28g26851kZ ~]#
例:在所有的#号所在行之下再添加一行 “test”
[root@iZ28g26851kZ ~]# sed ‘/^#/a \test‘ /etc/fstab
#
test
# /etc/fstab
test
# Created by anaconda on Mon Aug 11 16:27:41 2014
test
#
test
# Accessible filesystems, by reference, are maintained under ‘/dev/disk‘
test
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
test
#
test
UUID=e76a7b8d-20c2-4f94-bdd1-f4054a34c206 / ext4 defaults,barrier=0 1 1
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
[root@iZ28g26851kZ ~]#
例:将#号开头的行保存到test10.txt文件中
[root@iZ28g26851kZ ~]# sed ‘/^#/w test10.txt‘ /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Aug 11 16:27:41 2014
#
# Accessible filesystems, by reference, are maintained under ‘/dev/disk‘
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=e76a7b8d-20c2-4f94-bdd1-f4054a34c206 / ext4 defaults,barrier=0 1 1
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
[root@iZ28g26851kZ ~]# ls
exittest.sh libiconv-1.14 mhash-0.9.4.tar.gz mysql-5.1.51.tar.gz nginx-1.8.0.tar.gz test10.txt
filetest.sh libiconv-1.14.tar.gz mysql-5.1.51 nginx-1.8.0 shifttest.sh vartest.sh
[root@iZ28g26851kZ ~]# cat test10.txt
#
# /etc/fstab
# Created by anaconda on Mon Aug 11 16:27:41 2014
#
# Accessible filesystems, by reference, are maintained under ‘/dev/disk‘
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
[root@iZ28g26851kZ ~]#
例:将所有的 / 替换成 “@O@”
[root@iZ28g26851kZ ~]# sed ‘s#/#@O@#g‘ /etc/fstab
#
# @O@etc@O@fstab
# Created by anaconda on Mon Aug 11 16:27:41 2014
#
# Accessible filesystems, by reference, are maintained under ‘@O@dev@O@disk‘
# See man pages fstab(5), findfs(8), mount(8) and@O@or blkid(8) for more info
#
UUID=e76a7b8d-20c2-4f94-bdd1-f4054a34c206 @O@ ext4 defaults,barrier=0 1 1
tmpfs @O@dev@O@shm tmpfs defaults 0 0
devpts @O@dev@O@pts devpts gid=5,mode=620 0 0
sysfs @O@sys sysfs defaults 0 0
proc @O@proc proc defaults 0 0
[root@iZ28g26851kZ ~]#
之前说过sed所有的操作都是针对模式空间进行的,并不会影响到源文件,
那如果确实像将源文件修改掉呢?
那就使用-i选项
这样就直接操作的是源文件了,所以慎用~~
同时执行多个脚本
sed -e ‘AddressComment‘ -e ‘AddressComment‘ file ...
将脚本写到一个文件中,每一行为一个脚本,然后,,,
sed -f /xxx/xxx.xx file ...
支持扩展正则表达式
======================================
例:从文件目录中找出文件的目录
[root@iZ28g26851kZ ~]# echo "/test/test2/etc/passwd" | sed -r ‘s@^(/.*/).+/?@\1@‘
/test/test2/etc/
[root@iZ28g26851kZ ~]#
例:从文件目录中找出文件名
[root@iZ28g26851kZ ~]# echo "/test/test2/etc/passwd" | sed -r ‘s@^(/.*/)(.+)/?@\2@‘
passwd
[root@iZ28g26851kZ ~]#
标签:
原文地址:http://blog.csdn.net/jianshijiuyou/article/details/51354623