您的位置:首页 > 运维架构 > Linux

linux下sed的使用(下)

2014-04-07 21:28 351 查看
linux下sed的使用(下)本篇主要讲解:
---sed的导入和导出

sed数据的导入和导出(是一种非交互式的导入和导出,可用在脚本中)
r 导入 (把其他文件的内容放到当前文件里)
w 导出 (文件另存为)
Sed导入格式
sed -i ‘定址符r 文件A’ 文件B
把文件A的数据导入到 文件B里
导入的时候是逐行导入的,B文件必须事先存在,且最少有一行,一行都没有的情况下是导入不了的
默认会逐行导入

使用定址符限制输入数据的位置
定址符可以使用行号、正则表达式表示
Sed导出格式
sed -i ‘定址符w 文件A’ 文件B
把文件B的数据导出到 文件A里(另存为)
覆盖导出
文件A不用事先创建
若文件A事先存在 会覆盖其内的数据
一、
1.sed导入导出的基本用法

1)r 读入其他文件内容。
以前面的rclocal.txt文件为例,确认文件内容:
[root@svr5 ~]# cat rclocal.txt
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
.4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
6
7 touch /var/lock/subsys/local
读入/etc/sysconfig/network文件的全部内容,插入到rclocal.txt文件的第5行之后(注意:需加-i才真的保存,否则只输出结果):

[root@svr5 ~]# sed '5r /etc/sysconfig/network' rclocal.txt
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=svr5.tarena.com
6
7 touch /var/lock/subsys/local
在rclocal.txt文件的每一行下方都插入/etc/sysconfig/network文件的内容:

[root@svr5 ~]# sed 'r /etc/sysconfig/network' rclocal.txt
1 #!/bin/sh
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=svr5.tarena.com
2 #
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=svr5.tarena.com
3 # This script will be executed *after* all the other init scripts.
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=svr5.tarena.com
.. ..
2)w 将过滤结果保存到指定的文件。
以前面的rclocal.txt文件为例,确认文件内容:
[root@svr5 ~]# cat rclocal.txt
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
6
7 touch /var/lock/subsys/local
将rclocal.txt文件的第2-5行保存为/tmp/out.txt文件:

[root@svr5 ~]# sed -n '2,5w /tmp/out.txt' rclocal.txt
[root@svr5 ~]# cat /tmp/out.txt
2 #
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
上述操作与改用p重定向的效果相同:

[root@svr5 ~]# sed -n '2,5p' rclocal.txt > /tmp/out.txt
[root@svr5 ~]# cat /tmp/out.txt
2 #
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
再比如:将rclocal.txt文件中包含“init”的行保存为/tmp/out.txt文件:

[root@svr5 ~]# sed -n '/init/w /tmp/out.txt' rclocal.txt
[root@svr5 ~]# cat /tmp/out.txt
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
效果等同于:

[root@svr5 ~]# sed -n '/init/p' rclocal.txt > /tmp/out.txt
[root@svr5 ~]# cat /tmp/out.txt
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
2.sed的复制粘贴操作

1)基本动作指令
复制到剪贴板:
H:模式空间 ---[追加]--->保持空间
h:模式空间 ---[覆盖]--->保持空间
读取剪贴板内容并粘贴:
G:保持空间 ---[追加]--->模式空间
g:模式空间 ---[覆盖]--->保持空间
若要实现“剪切”操作,实际上就是先“复制”再“删除”。
讲一下sed的2个空间:
模式空间
--存放当前处理的行,将处理结果输出
--若当前行不符合处理条件,则原样输出
--处理完当前行再读入下一行来处理
保持空间:

--作用类似于”剪贴板“
--默认存放一个空行(换行符\n)
2)复制操作练习
还以rclocal.txt文件为例:

[root@svr5 ~]# cat rclocal.txt
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
6
7 touch /var/lock/subsys/local
将第rclocal.txt文件的第1-3行内容复制到文件末尾:

[root@svr5 ~]# sed '1,3H;$G' rclocal.txt
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
6
7 touch /var/lock/subsys/local
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
从上述结果可以发现,使用G粘贴操作的效果是追加。但是,文件原内容与新追加的文本之间还有一个空行,这是怎么来的呢?这是保持空间默认的内容“\n”,追加操作时就保留了。那么,如果将G追加改为g覆盖来粘贴,结果会怎么样呢?看看:

[root@svr5 ~]# sed '1,3H;$g' rclocal.txt
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
6
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
什么情况?把原文件的最后一行给覆盖了。如果既要保留原文件的所有内容,又想复制前3行到文件末尾,而且不希望有空行分开,怎么办呢?把复制操作H追加改成h覆盖试试看什么结果:
[root@svr5 ~]# sed '1,3h;$G' rclocal.txt
1#!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
6
7 touch /var/lock/subsys/local
8 # This script will be executed *after* all the other init scripts.
这下原文件内容是保留了,空行也没了,但是追加的内容却只有第3行,为什么?

因为sed是逐行处理的,所以每次h覆盖操作都会清空原来存放在保持空间的文本,也就是说用h复制第1行到保持空间后,默认的“\n”就没了;再用h复制第2行到保持空间后,前一次复制过去的第1行文本又没了;再用h复制第3行到保持空间后,前一次复制过去的第2行文本又没了,…… 于是,最终只有匹配的最后一行能够成功添加。
总和上述分析,我们可以在复制第一行的时候用h覆盖,而以后的每一行用H追加,这样就可以完美无空行的追加匹配行了:

[root@svr5 ~]# sed '1h;2,3H;$G' rclocal.txt
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
6
7 touch /var/lock/subsys/local
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
3)剪切操作练习

将rclocal.txt文件的第1-4行转移到文件末尾:
[root@svr5 ~]# sed '1{h;d};2,4{H;d};$G' rclocal.txt
5 # want to do the full Sys V style init stuff.
6
7 touch /var/lock/subsys/local
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
将包含单词“init”的行剪切到文件末尾,保留默认的空行分隔:

[root@svr5 ~]# sed '/\<init\>/{H;d};$G' rclocal.txt
1 #!/bin/sh
2 #
4 # You can put your own initialization stuff in here if you don't
6
7 touch /var/lock/subsys/local
3 # This script will be executed *after* all the other init scripts.
5 # want to do the full Sys V style init stuff.
二、扩展

1.sed逐字符替换
sed的s操作可实现字符串替换,而另一个操作y操作可实现逐个字符替换。
什么意思呢?对比一下:
's/OLD/NEW/g' ,处理方式为整串匹配,只匹配完整的字符串“OLD”,对单个字符“O”、“L”或者“D”无效,而且替换前后的字符串长度可以不相同(比如,“OLD”可替换为“NEWNEW”)。实现的效果是——将文本中所有的字符串“OLD”替换为“NEW”。
'y/abcd/ABCD/',处理的方式为逐个字符依次替换,替换前后的内容必须一一对应、数量一致。实现的效果是——将文件内所有的字符“a”替换为“A”、字符“b”替换为“B”、字符“c”替换为“C”、字符“d”替换为“D”。
下面仍以rclocal.txt文件为例,测试一下y操作的相关效果。
确认rclocal.txt文件内容:
[root@svr5 ~]# cat rclocal.txt
1 #!/bin/sh
.2 #
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
6
7 touch /var/lock/subsys/local
1)将所有的小写字母i替换为大写的I:

[root@svr5 ~]# sed 'y/i/I/' rclocal.txt
1 #!/bIn/sh
2 #
.3 # ThIs scrIpt wIll be executed *after* all the other InIt scrIpts.
4 # You can put your own InItIalIzatIon stuff In here If you don't
5 # want to do the full Sys V style InIt stuff.
.6
7 touch /var/lock/subsys/local
等效于:

[root@svr5 ~]# sed 's/i/I/g' rclocal.txt
1 #!/bIn/sh
2 #
3 # ThIs scrIpt wIll be executed *after* all the other InIt scrIpts.
4 # You can put your own InItIalIzatIon stuff In here If you don't
5 # want to do the full Sys V style InIt stuff.
6
7 touch /var/lock/subsys/local
2)将所有的小写字母a、e、l替换为大写:

[root@svr5 ~]# sed 'y/ael/AEL/' rclocal.txt
1 #!/bin/sh
2 #
3 # This script wiLL bE ExEcutEd *AftEr* ALL thE othEr init scripts.
4 # You cAn put your own initiALizAtion stuff in hErE if you don't
5 # wAnt to do thE fuLL Sys V styLE init stuff.
6
7 touch /vAr/Lock/subsys/LocAL
等效于:

[root@svr5 ~]# sed 's/a/A/g;s/e/E/g;s/l/L/g' rclocal.txt
1 #!/bin/sh
2 #
3 # This script wiLL bE ExEcutEd *AftEr* ALL thE othEr init scripts.
4 # You cAn put your own initiALizAtion stuff in hErE if you don't
5 # wAnt to do thE fuLL Sys V styLE init stuff.
6
7 touch /vAr/Lock/subsys/LocAL
3)将所有的字符a变为数字1、字符e变为数字5、字符l变为变为字符X:

[root@svr5 ~]# sed 'y/ael/159/' rclocal.txt
1 #!/bin/sh
2 #
3 # This script wi99 b5 5x5cut5d *1ft5r* 199 th5 oth5r init scripts.
4 # You c1n put your own initi19iz1tion stuff in h5r5 if you don't
5 # w1nt to do th5 fu99 Sys V sty95 init stuff.
6
7 touch /v1r/9ock/subsys/9oc19
2.单词的大小写转换

将匹配结果转大写可用\U&、转小写可用\L&,这里的&为调用的匹配串。
还以前面的rclocal.txt文件为例,确认内容如下:
[root@svr5 ~]# cat rclocal.txt
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
.4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
6
7 touch /var/lock/subsys/local
1)将所有的小写字母转为大写:

[root@svr5 ~]# sed 's/[a-z]/\U&/g' rclocal.txt
1 #!/BIN/SH
2 #
3 # THIS SCRIPT WILL BE EXECUTED *AFTER* ALL THE OTHER INIT SCRIPTS.
4 # YOU CAN PUT YOUR OWN INITIALIZATION STUFF IN HERE IF YOU DON'T
5 # WANT TO DO THE FULL SYS V STYLE INIT STUFF.
6
7 TOUCH /VAR/LOCK/SUBSYS/LOCAL
等效于:

[root@svr5 ~]# cat rclocal.txt | tr [:lower:] [:upper:]
1 #!/BIN/SH
2 #
3 # THIS SCRIPT WILL BE EXECUTED *AFTER* ALL THE OTHER INIT SCRIPTS.
4 # YOU CAN PUT YOUR OWN INITIALIZATION STUFF IN HERE IF YOU DON'T
5 # WANT TO DO THE FULL SYS V STYLE INIT STUFF.
6
7 TOUCH /VAR/LOCK/SUBSYS/LOCAL
2)将所有的大写字母转为小写:

[root@svr5 ~]# sed 's/[A-Z]/\L&/g' rclocal.txt
1 #!/bin/sh
2 #
3 # this script will be executed *after* all the other init scripts.
4 # you can put your own initialization stuff in here if you don't
5 # want to do the full sys v style init stuff.
6
7 touch /var/lock/subsys/local
等效于:

[root@svr5 ~]# cat rclocal.txt | tr [:upper:] [:lower:]
1 #!/bin/sh
2 #
3 # this script will be executed *after* all the other init scripts.
4 # you can put your own initialization stuff in here if you don't
5 # want to do the full sys v style init stuff.
6
7 touch /var/lock/subsys/local
3)将每个单词的首字母大写:

[root@svr5 ~]# sed -r 's/\b[a-Z]/\U&/g' rclocal.txt
1 #!/Bin/Sh
2 #
3 # This Script Will Be Executed *After* All The Other Init Scripts.
4 # You Can Put Your Own Initialization Stuff In Here If You Don'T
5 # Want To Do The Full Sys V Style Init Stuff.
6
7 Touch /Var/Lock/Subsys/Local
4)将每个单词的首字母大写,其余字母小写:

[root@svr5 ~]# sed -r 's/([a-Z])([a-Z]+)/\U\1\L\2/g' rclocal.txt
1 #!/Bin/Sh
2 #
3 # This Script Will Be Executed *After* All The Other Init Scripts.
4 # You Can Put Your Own Initialization Stuff In Here If You Don't
5 # Want To Do The Full Sys V Style Init Stuff.
6
7 Touch /Var/Lock/Subsys/Local
总结:
1、若要实现“剪切”操作,实际上就是先“复制”再“删除”。
2、因为保持空间默认会有一个换行符号,所以把模式空间的内容放到保持空间的时候,第一行用h覆盖来把换行符给覆盖掉,这样就不会出现一行空格
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息