sed
2017-01-23 15:08
295 查看
sed
sed是一种非交互式文本编辑器,默认不修改原文件,主要用来将数据进行选取、替换、删除、新增。 工作原理:一行一行处理,从文件的第一行开始读取,放到模式空间中进行相应处理,处理完将结果输出到屏幕上,然后继续读取下一行,直到所有的行都处理完毕,sed结束。sed一般用于处理大文件。
常用选项:
-n:静默输出,关闭模式空间的输出,一般与p一起用
-e:允许进行多项编辑,也就是说对同一行做多次处理、也可以做多点编辑,-e ‘动作’ -e ‘动作’ 等价于 ‘动作1;动作2’
-f sed脚本 : 指定运行的sed脚本的
-r:允许使用扩展正则
-i:直接修改原文件
动作:
a \: 追加,在当前行后添加一行或多行。添加多行时,除最后 一行外,每行末尾需要用“\”代表数据未完结。
c \: 行替换,用 c 后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾需用“\”代表数据未完结。
i \: 插入,在当前行前插入一行或多行。插入多行时,除最后 一行外,每行末尾需要用“\”代表数据未完结。
常用命令
1.“d”: 删除,删除指定的行。
样例文件是/etc/passwd前五行
[root@localhost ~]# cat sed_example.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
删除第3行和删除1-3行
[root@localhost ~]# sed '3d' sed_example.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin [root@localhost ~]# sed '1,3d' sed_example.txt adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
2.“p”,打印,输出指定的行。前面一定要加-n
例如输出第3行,如果不加-n,会输出两遍第三行(因为模式空间中的内容也会输出)
[root@localhost ~]# sed '3p' sed_example.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin [root@localhost ~]# sed -n '3p' sed_example.txt daemon:x:2:2:daemon:/sbin:/sbin/nologin
“!”表示”非”,例如’3!d’和’3p’输出结果一样。
[root@localhost ~]# sed '3!d' sed_example.txt daemon:x:2:2:daemon:/sbin:/sbin/nologin
3.“r”读取,读取后面文件内容并输出
[root@localhost ~]# sed '/^root/r /etc/issue' sed_example.txt root:x:0:0:root:/root:/bin/bash Red Hat Enterprise Linux Server release 6.5 (Santiago) Kernel \r on an \m bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
5.“w”保存,将匹配到的结果保存到指定文件中
[root@localhost ~]# sed '/root/w /tmp/sed.txt' sed_example.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin [root@localhost ~]# cat /tmp/sed.txt root:x:0:0:root:/root:/bin/bash
6.“a”追加,在匹配到的行下一行插入内容
[root@localhost ~]# sed '/root/a hello' sed_example.txt root:x:0:0:root:/root:/bin/bash hello bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
在最后一行插入内容
[root@localhost ~]# sed '$a the end' sed_example.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin the end
7.“i”在匹配到的上一行插入内容
[root@localhost ~]# sed '/daemon/i example' sed_example.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin example daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin [root@localhost ~]# sed '3i example' sed_example.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin example daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
8.“c”修改,本行替换,将匹配到的行的内容替换成新内容
[root@localhost ~]# sed '/root/c ROOT' sed_example.txt ROOT bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
9.“y”, 转换的命令,对应替换,“y/ / /”不可以使用正则表达式
[root@localhost ~]# sed 'y/root/ROOT/' sed_example.txt ROOT:x:0:0:ROOT:/ROOT:/bin/bash bin:x:1:1:bin:/bin:/sbin/nOlOgin daemOn:x:2:2:daemOn:/sbin:/sbin/nOlOgin adm:x:3:4:adm:/vaR/adm:/sbin/nOlOgin lp:x:4:7:lp:/vaR/spOOl/lpd:/sbin/nOlOgin
10.“n”,处理匹配的下一行,{}里面写多个命令,之间用分号分隔
[root@localhost ~]# sed -n '/root/p' sed_example.txt root:x:0:0:root:/root:/bin/bash [root@localhost ~]# sed -n '/root/{n;p}' sed_example.txt bin:x:1:1:bin:/bin:/sbin/nologin
11.“q”,退出,不再向模式空间读入新行
[root@localhost ~]# sed '/^bin/q' sed_example.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin
12.“s”,查找替换
定址s/模式匹配(旧的内容)/新的内容/[修饰符]
除了“/”,还有“#”“@”“%”三种符号也行
修饰符:
g:全局替换,一行中的多个
n:n为数字,1-512 替换第n个匹配到的内容
p:打印
w:另存为,写
[root@localhost ~]# sed 's/root/ROOT/' sed_example.txt //默认只替换第一次匹配到的 ROOT:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin [root@localhost ~]# sed 's/root/ROOT/2' sed_example.txt //替换每行中第2个匹配到的 root:x:0:0:ROOT:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin [root@localhost ~]# sed 's/root/ROOT/g' sed_example.txt //全部替换 ROOT:x:0:0:ROOT:/ROOT:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
模式匹配时的特殊符号
“^”每行的开头
给全文加注释#
[root@localhost ~]# sed 's/^/#/g' sed_example.txt #root:x:0:0:root:/root:/bin/bash #bin:x:1:1:bin:/bin:/sbin/nologin #daemon:x:2:2:daemon:/sbin:/sbin/nologin #adm:x:3:4:adm:/var/adm:/sbin/nologin #lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
在第3到4行的开头每行加上###
[root@localhost ~]# sed '3,4s/^/###/g' sed_example.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin ###daemon:x:2:2:daemon:/sbin:/sbin/nologin ###adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
“$”每行的结尾
在匹配到root的行的末尾添加###
[root@localhost ~]# sed '/root/s/$/###/g' sed_example.txt root:x:0:0:root:/root:/bin/bash### bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
二.“-r”选项,支持扩展正则
[root@localhost ~]# cat sed_example2.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin [root@localhost ~]# sed -r 's/[[:space:]]+//g' sed_example2.txt //"[[:space:]]+"表示空格出现一次以上 root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
(1). “&”引用,用来代替匹配到的模式的内容,将每一行的出现的数字加上括号
[root@localhost ~]# sed -r 's/[0-9]+/(&)/g' sed_example.txt root:x:(0):(0):root:/root:/bin/bash bin:x:(1):(1):bin:/bin:/sbin/nologin daemon:x:(2):(2):daemon:/sbin:/sbin/nologin adm:x:(3):(4):adm:/var/adm:/sbin/nologin lp:x:(4):(7):lp:/var/spool/lpd:/sbin/nologin
(2).“\n”表示引用模式匹配中的第n个()中的内容
[root@localhost ~]# cat sed_example3.txt hello, i like you hi, my love [root@localhost ~]# sed -r 's/(l..e)/\1r/' sed_example3.txt hello, i liker you hi, my lover
三.sed的贪婪性
[root@localhost ~]# cat sed_example4.txt aaaa 1234 hello, i like you dddd hello, my love cccc hello, i miss you ffff [root@localhost ~]# sed -n '/hello/,/hello/p' sed_example4.txt hello, i like you dddd hello, my love hello, i miss you ffff
这是由于sed匹配的贪婪性造成的。sed工具一次处理一行的内容,当找到第一次出现hello的行以后,它会对这个行做个标记,比如为1。然后继续寻找第二次出现hello的行,标记为2(注意:无论这行中有多少个hello,都算在一行来处理),然后将这几行的内容打印出来。但是这个文件内容还没扫描完,它会继续往下扫描,继续寻找第三次出现hello的行,作为第一个匹配的项,标记为3,再继续往下寻找第4次出现hello的行,作为第二个匹配的项,如果找到了,再接着把这几行的内容打印出来,然后再依照这样的原理继续寻找下去,直到文件结束。但是在这期间还会有一个小插曲,就是当出现hello的行不是偶数行时,那最后一次出现hello的行以及下面的所有内容都会被打印出来。