一、什么是sed:
sed
流编辑器 (stream editor) 是个有用的文本解析和操作实用工具,可以方便地进行文件或数据流的转换。它一次一行地读取文本,在文本行中应用指定的命令,默认输出到 stdout。
sed的工作模式是
:处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。
二、sed的使用
sed的使用格式为:
sed [OPTION]... 'script' [input-file] ...
[OPTION]:
-n:不输出模式空间中的内容至屏幕;
-e script, --expression=script:多点编辑;
-f /PATH/TO/SED_SCRIPT_FILE 执行里面的COMMAND
-r, --regexp-extended:支持使用扩展正则表达式;
-i[SUFFIX], --in-place[=SUFFIX]:直接编辑原文件 ,做此操作时请慎重。
‘script’中包括地址定界,匹配模式,编辑命令
1、地址定界:
(1) 空地址:对全文进行处理;
(2) 单地址:
#:指定行;
/pattern/:被此模式所匹配到的每一行;
(3) 地址范围
#,#:如1,10 表示1到10行之间
#,+#:如1,+10 表示1到11行之间
#,/pat1/:如 1,/pat1/表示从第一行到第一次被pat1匹配到行之间
/pat1/,/pat2/:表示第一次被pat1匹配到的行到第一次被pat2匹配到的行之间
$:最后一行;
(4) 步进:~
1~2:所有奇数行
2~2:所有偶数行
2、匹配模式
与grep一样,sed也支持特殊元字符,来进行模式查找、替换。不同的是,sed使用的正则表达式是括在斜杠线"/"之间的模式,在这里就不再重述,如果有不明白的地方可以参考之前的grep的相关介绍。
3、编辑命令:
d:删除;
p:显示模式空间中的内容;
a \text:在行后面追加文本“text”,支持使用\n实现多行追加;
i \text:在行前面插入文本“text”,支持使用\n实现多行插入;
c \text:把匹配到的行替换为此处指定的文本“text”;
w /PATH/TO/SOMEFILE:保存模式空间匹配到的行至指定的文件中;
r /PATH/FROM/SOMEFILE:读取指定文件的内容至当前文件被模式匹配到的行后面;文件合并;
=:为模式匹配到的行打印行号;
!:条件取反;使用方法:地址定界!编辑命令;
s///:查找替换,其分隔符可自行指定,常用的有s@@@, s###等;
替换标记:
g:全局替换;
w /PATH/TO/SOMEFILE:将替换成功的结果保存至指定文件中;
p:显示替换成功的行;
三、sed命令的使用实践:
1、删除/boot/grub/grub2.cfg文件中所有以空白字符开头的行的行首的所有空白字符;
使用命令前:
[root@bogon ~]# cat /etc/grub2.cfg | head -20 # # DO NOT EDIT THIS FILE # # It is automatically generated by grub2-mkconfig using templates # from /etc/grub.d and settings from /etc/default/grub # ### BEGIN /etc/grub.d/00_header ### set pager=1 if [ -s $prefix/grubenv ]; then load_env fi if [ "${next_entry}" ] ; then set default="${next_entry}" set next_entry= save_env next_entry set boot_once=true else set default="${saved_entry}"
使用命令后:
[root@bogon ~]# sed 's@^[[:space:]]\+@@' /etc/grub2.cfg |head -20 # # DO NOT EDIT THIS FILE # # It is automatically generated by grub2-mkconfig using templates # from /etc/grub.d and settings from /etc/default/grub # ### BEGIN /etc/grub.d/00_header ### set pager=1 if [ -s $prefix/grubenv ]; then load_env fi if [ "${next_entry}" ] ; then set default="${next_entry}" set next_entry= save_env next_entry set boot_once=true else set default="${saved_entry}"
2、删除/etc/fstab文件中所有以#开头的行的行首的#号及#后面的所有空白字符
使用sed前:
[root@bogon ~]# cat /etc/fstab # # /etc/fstab # Created by anaconda on Tue Mar 8 03:47:15 2016 # # 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 # /dev/mapper/centos-root / xfs defaults 0 0 UUID=26520fc2-e8b6-4a80-b600-8dc08c108c34 /boot xfs defaults 0 0 /dev/mapper/centos-swap swap swap defaults 0 0 /dev/sr0 /media/CentOS iso9660 defaults 0 0
使用sed后:
[root@bogon ~]# sed 's@^#[[:space:]]*@@' /etc/fstab /etc/fstab Created by anaconda on Tue Mar 8 03:47:15 2016 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 /dev/mapper/centos-root / xfs defaults 0 0 UUID=26520fc2-e8b6-4a80-b600-8dc08c108c34 /boot xfs defaults 0 0 /dev/mapper/centos-swap swap swap defaults 0 0 /dev/sr0 /media/CentOS iso9660 defaults 0 0 [root@bogon ~]#
3、输出一个绝对路径给sed命令,取出其目录,其行为类似于dirname
[root@bogon ~]# echo "/var/log/messages/" | sed 's@[^/]\+/\?$@@' /var/log/