sed Stream Editor
sed 是一个文件编辑工具,把所有文件加载到内存的缓存区中,按换行符进行读取,一次从缓存区中读取一行到自己的内部空间,并完成编辑,并将结果输出到屏幕上,默认sed不会对原文件进行更改。
sed 使用格式:
sed [options] ‘addr1[,addr2]编辑命令‘ FILE ... sed [options] “addr1[,addr2]编辑命令” FILE ... \\ 当有变量替换时,使用双引号
常用选项(options):
-n:静默模式,不输出模式空间中的内容;
-r:扩展的正则表达式
-f /path/to/sed_script_file:指定sed脚本文件
-e ‘script‘ -e ‘script‘:指定多个编辑指令
-i:直接编辑原文件
编辑命令:
d: 删除
p: 打印
sed -n ‘/^#/,/^\//p‘ /etc/fstab \\ 如果不用选项n会把模式空间的内容也一并输出
i \text:
# sed ‘/^#/i \begin‘ test.txt \\ 在每个#号开头的行前插入一行begin
a \text: 后面
r /path/to/somefile: 在指定位置把另外一个文件的内容插入进来
w /path/to/somefile:将符合条件的所有行保存至指定的文件中
=:显示符合条件的行的行号
sed -n ‘/^\//=‘ /etc/fstab
y:字符转换
sed ‘/^#/y/abcdefg/ABCDEFG/‘ test.txt
s///: 查找条件可以使用模式,但要替换的内容不行
地址定界:
number:指定输入文件的唯一行.
startline,endline:指定开始行和结束的行如:1,5表示从1行开始到第五行结束。
/pat1/,/pat2/ :第一个被模式匹配到的行到,最后一个被模式匹配到的行
# sed -n ‘/^#/,/[[:digit:]]/p‘ test.txt
/pattern/ :被模式匹配到的行,中间包含正则表达式,如果中间为空则匹配最近一次正则表达式。
addr1,+N:匹配地址1以及后面的N行内容,如3,+4,表示从3行开始及后面4行的内容。
# sed ‘3,+4d‘ test.txt
\cpatternc:\c与c之间匹配扩展正则表达式,c字符可以是任意字符。
部份指令详解:
查找替换s,格式如下
# sed ‘[address]s/pattern/replacement/flags‘
address为地址定界,省略代表全文搜索。
s为替换指定
pattern为匹配的模式
replacement 为需要替换的内容
flags为标记,g 为全局替换,p打印模式空间中的内容,i: ignore-case,不区分字符大小写
示例:
如果一个指定过长,这时有必要使用-f选项指定sed脚本文件,在脚本文件中可以包含多行指令来对文件进行修改
原文件:
DEVICE=eth0
TYPE=Ethernet
ONBOOT=no
NM_CONTROLLED=yes
BOOTPROTO=none
NETMASK=255.255.255.0
gateway=192.168.0.1
DNS1=114.114.114.114
脚本
/.*/{
/ONBOOT/c ONBOOT=yes \\ 替换
/NETMASK/i IPADDR=192.168.0.29 \\ 插入
/gateway/y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/ \\ 转换
}
执行结果
# sed -f sed.sh ifcfg-eth0 DEVICE=eth0 TYPE=Ethernet ONBOOT=yes NM_CONTROLLED=yes BOOTPROTO=none IPADDR=192.168.0.29 NETMASK=255.255.255.0 GATEWAY=192.168.0.1 DNS1=114.114.114.114
2、匹配以UUID开头的行,把/etc/issue中的内容读取到匹配到的内容后面
# sed ‘/^UUID/r /etc/issue‘ /etc/fstab
3、将匹配到的行保存至/tmp/filetable.txt,是覆盖式添加的
# sed ‘/^\//w /tmp/filetable.txt‘ /etc/fstab
4、有如下内容文件
He like his liker.
He like his lover.
She love her liker.
She love her lover.
(1)、删除以上内容当中包含单词“l..e”前后一致的行;
# sed ‘/\(l..e\).*\1/d‘ test
(2)、将文件中“l..e”前后一致的行中,最后一个l..e词首的l换成大写L;
# sed ‘s/\(\(l\(..e\)\).*\)\2/\1L\3/g‘ test
练习:
1、替换/etc/inittab文件中“id:3:initdefault:”一行中的数字为5;
# sed ‘[email protected]\(id:\)[0-9]\(:initdefault\)@\15\[email protected]‘ /etc/inittab
2、删除/etc/init.d/funcions文件中的空白行;
# sed ‘/^$/d‘ /etc/ini.t/functions
3、删除/etc/inittab文件中位于行首的#;
# sed ‘[email protected]^#@@g‘ /etc/initta
4、删除/etc/rc.d/rc.sysinit文件中以#后跟至少一个空白字符开头的行的行首的#和空白字符;
# sed ‘[email protected]^#[[:space:]]\{1,\}@@g‘ /etc/rc.d/rc.sysinit
5、删除/boot/grub/grub.conf文件中行首的空白字符;
# sed ‘[email protected]^[[:space:]]\{1,\}@@‘ /boot/grub/grub.conf
6、取出一个文件路径的目录名称,如/etc/sysconfig/network,其目录为/etc/sysconfig,功能类似dirname命令;
# echo /etc/sysconfig/network-scripts/ifcfg-eth0/ | sed ‘[email protected][^/]\{1,\}/*[email protected]@‘
意思找最后一个以/开头的字符串,后面跟着可有可无的/替换成什么也没有