1、命令说明:
sed是一种行编辑器,它是文本处理中非常好用的工具,能够完美的配合正则表达式使用。处理文本时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容输出至屏幕,接着处理下一行,这样不断重复,直至文件末尾。文件内容并不会被改变,除非使用重定向存储输出。sed主要用来自动编辑一个或多个文件,可以将数据行进行替换、删除、新增、选取等特定工作,简化对文件的反复操作。
2、基本格式:
命令格式:# sed [options] 'command' file(s)
脚本格式:# sed [options] -f scriptfile file(s)
sed脚本是sed的命令清单,启动sed时以-f选项引导脚本文件名。sed对于脚本中输入的命令非常严格,在命令的末尾不能有任何空白。如果在一行中有多个命令,要用分号分隔。以#开头的行为注释行,且不能跨行。
3、常用选项:
-n:只打印模式匹配的行
-e:多点编辑,允许在同一行里执行多条命令
-f scriptfile:将sed的动作写在一个文件内,用-f scriptfile执行scriptfile内的sed动作
-r:支持使用扩展正则表达式
-i:直接修改源文件内容
4、地址定界:
0地址(不给地址):对全文进行处理
单地址:
#:指定第#行
/pattern/:被此模式所能够匹配到的每一行
地址范围:
#,#:指定行的范围
/pat1/,/pat2/:从被模式pat1所能够匹配到的行至被模式pat2所能够匹配到的行
#,/pat1/:从指定的行至被模式pat1所能够匹配到的行
步进(~):
1~2:读取所有奇数行
2~2:读取所有偶数行
5、编辑命令:
d:删除指定的行
p:打印模式空间中的内容
a \text:在行下追加文本,支持使用\n实现多行追加
i \text:在行上插入文本,支持使用\n实现多行插入
c \text:将指定内容替换为单行或多行文本
w filename:保存模式空间匹配到的行至指定文件中
r filename:读取指定文件的内容至模式空间中匹配到的行的行后,如果匹配多行,则内容将显示在所有匹配行的下面
=:为模式空间中的行打印行号
!:对地址定界取反
s:替换指定字符,默认只查找替换一行中第一次出现的。支持使用s@@@、s###、s///等格式的分隔符
g:行内全部替换,替换每一行中的所有匹配
Ng:从第N处匹配开始替换
p:打印替换成功的行
&:已匹配字符串标记
\1:子串匹配标记,匹配给定样式的其中一部分
w filename:将替换成功的结果保存至指定文件中
6、高阶命令:
h:把模式空间中的内容覆盖至保持空间
H:把模式空间中的内容追加至保持空间
g:从保持空间中取出数据覆盖至模式空间
G:从保持空间取出内容追加至模式空间
x:把模式空间中的内容与保持空间中的内容进行互换
n:读取匹配到的行的下一行至模式空间
N:追加匹配到的行的下一行至模式空间
d:删除模式空间中的行
D:删除多行模式空间中的所有行
7、使用示例:
以下列举的各示例,如没有特殊说明,即为/tmp/test.txt
(1)删除以1开头的行:# sed '/^1/d' /tmp/test.txt
(2)删除第3行至末尾的所有行:# sed '3,$d' /tmp/test.txt
(3)删除文中所有的空白行:# sed '/^$/d' /tmp/test.txt
(4)删除文件/boot/grub/grub.conf中所有以空白开头的行行首的空白字符:
# sed 's@^[[:space:]]\+@@' /boot/grub/grub.conf
(5)只打印以2开头的行的内容:# sed -n '/^2/p' /tmp/test.txt
-n选项+p命令实现的效果和单独使用d命令正好相反:# sed '/^2/d' /tmp/test.txt
不能表示成:# sed '/^2/p' /tmp/test.txt,sed命令默认就会显示模式空间中的内容,再加p,会输出2遍
(6)打印除第4行以外的所有行的内容:# sed -n '4!p' /tmp/test.txt
效果等同于:# sed '4d' /tmp/test.txt
(7)在以3开头的行的行后追加2行hello world:# sed '/^3/a \hello world\nhello world' /tmp/test.txt
(8)在以5开头的行的行前插入1行welcome marion:# sed '/^5/i \welcome marion' /tmp/test.txt
(9)将以6开头的行的内容替换为2行hello world:# sed '/^6/c \hello world\nhello world' /tmp/test.txt
(10)将文件第2-5行中的内容保存至文件/tmp/bak.txt中:# sed -n '2,5w /tmp/bak.txt' /tmp/test.txt
(11)将文件/etc/issue中的内容追加至以1开头的行的行后:# sed '/^1/r /etc/issue' /tmp/test.txt
(12)打印3-6行的行号:# sed '3,6=' /tmp/test.txt
(13)打印被模式/test/和/check/匹配范围内的所有行:# sed -n '/test/,/check/p' /tmp/test.txt
(14)变量引用并替换:
sed表达式可以使用单引号来引用,但是如果表达式内部包含变量字符串,就必须使用双引号
(15)按照需求将输入的字符串中的root替换成ROOT:
(16)将文件第3行至第一个包含以aaAA开头的行之间的所有行的末尾用字符串aaa bbb替换并打印:
# sed -n '3,/^aaAA/s#$#aaa bbb#p' /tmp/test.txt
(17)将所有以192.168.0.1开头的行都替换成它自已加localhost:# sed's@^192.168.0.1@&localhost@' /etc/hosts
(18)将文件/etc/passwd中所有以r开头、以t结尾的4位长度字符串都加上er结尾,并打印这些行:
# sed -n 's#r..t#&er#gp' /etc/passwd
(19)将输入的字符串中每个单词都加上[]:# echo "this is a test line" | sed 's#\w\+#[&]#g'
正则表达式\w\+匹配输入的字符串中的每一个单词,使用[&]替换它,&对应于之前所匹配到的单词
(20)将输入的字符串中的digit加上数字直接替换成数字,去除字符串digit:
# echo "this is digit 7 in a number" | sed 's#digit \([0-9]\)#\1#'
\(..\):用于匹配子串,对于匹配到的第一个子串就标记为\1,依此类推匹配到的第二个结果就为\2
(21)将输入的字符串中的aaa位置和BBB互换:# echo "aaa BBB" | sed 's@\([a-z]\+\) \([A-Z]\+\)@\2 \1@'
(22)将输入的字符串中所有love后加上rs:# echo "like-love-like-love" | sed 's/\(love\)/\1rs/g'
(23)将文件中第1-2行中的abcd和ABCD进行大小写转换:
(24)echo一个绝对路径,通过sed取出其目录名:
# echo "/tmp/test.txt" | sed 's@[^/]\+/\?$@@'
# echo "/var/log/messages" | sed 's@[^/]\+/\?$@@'
# echo "/etc/sysconfig/network-scripts/ifcfg-eth0" | sed's@[^/]\+/\?$@@'
(25)删除第1和第2行,并将aa替换为AA:# sed -e '1,2d' -e 's/aa/AA/g' /tmp/test.txt
(26)打印文件的奇数行:
# sed 'n;d' /tmp/test.txt
# sed -n '1~2p' /tmp/test.txt
(27)打印文件的偶数行:
# sed -n 'n;p' /tmp/test.txt
# sed -n '2~2p' /tmp/test.txt
(28)逆序打印文件的内容:# sed '1!G;h;$!d' /tmp/test.txt
(29)打印文件的最后两行内容:# sed '$!N;$!D' /tmp/test.txt
(30)打印文件的最后一行内容:# sed '$!d' /tmp/test.txt
(31)在文件每行下面加行空白行:# sed 'G' /tmp/test.txt
(32)合并文件中原有的连续空白行,并在行后追加空白行:# sed '/^$/d;G' /tmp/test.txt
(33)如果行内有字符串bcd,则移动至该行的下一行,替换这行的aa为bb,并打印该行:
# sed '/bcd/{n;s/aa/bb/g}' /tmp/test.txt