linux下sed的使用(上)
介绍sed的使用,其中主要包括sed文本处理、文本块处理、sed的导入和导出。
简介:
sed全称是Stream EDdit,即流编辑器。他的特点如下:
--非交互,基于模式匹配的过滤及修改文本;
--逐行处理,并将结果输出到屏幕上;
--可实现对文本的输出、删除、替换、复制、剪切、导入、导出等各种操作;
--他有两个空间,模式空间和保持空间,主要在导入导出的时候着重讲解。
sed文本处理:
一、sed命令的基本用法
1)命令格式
格式1:前置命令 | sed [选项] '编辑指令'
格式2:sed [选项] '编辑指令' 文件.. ..
编辑指令说明如下:
-
其中,“编辑指令”用来实现过滤操作,由“[定址符]+处理动作”组成;
-
而“定址符”用来定义需要操作的文本,由“[地址1,[地址2]]组成,地址1为起始位置,地址2为结束位置;
-
未指定“定址符”时,默认处理所有文本;
-
只指定地址1时,只处理与地址1相匹配的文本。
二、sed常用选项解释:
1
2
3
4
5
6
7
8
9
|
-n :屏蔽输出源数据 -i:直接对源文件进行操作 -f:使用 sed 脚本,对文件进行处理
-r:去掉正则表达式的转义符号和其他选项一起使用时放在首位 或者用转义符号 '\'
-e:指定多个处理动作,多个处理动作之间用分号;间隔 -p:打印输出 -d:删除 {}:可徐和多个命令组,以分号间隔 |
各选项使用示例:
1."-n"选项
执行p打印等过滤操作时,希望看到的是符合条件的文本。但不使用任何选项时,默认会将原始文本一并输出,从而干扰过滤效果。比如,尝试用sed输出/etc/rc.local的第1行,可以发现所有的行都被显示出来了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
root@tbj:~ # sed '1p' /etc/rc.local
#!/bin/sh -e #!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. exit 0
|
正确的用法应该添加"-n"选项,这样就可以只显示第1行了:
1
2
|
root@tbj:~ # sed -n '1p' /etc/rc.local
#!/bin/sh -e |
而在执行删除等过滤操作时,希望看到的是删除符合条件的文本之后还能够被保留下来的文本,所以这时候就不应该使用"-n"选项了。比如,删除/etc/rc.local文件的第1-4行文本:
1
2
3
4
5
6
7
8
9
10
11
|
root@tbj:~ # sed '1,4d' /etc/rc.local
# This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. exit 0
|
2."-i"选项
正常情况下,sed命令所做的处理只是把操作结果(包括打印、删除等)输出到当前终端屏幕,而并不会对原始文件做任何更改:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[root@svr5 ~] # cp /etc/rc.local rclocal.txt //复制为新文件,用作测试
[root@svr5 ~] # cat rclocal.txt //确认测试文件内容
#!/bin/sh # # This script will be executed *after* all the other init scripts. # You can put your own initialization stuff in here if you don't # want to do the full Sys V style init stuff. touch /var/lock/subsys/local
[root@svr5 ~] # sed '1,4d' rclocal.txt //删除第1~4行,输出结果
# want to do the full Sys V style init stuff. touch /var/lock/subsys/local
[root@svr5 ~] # cat rclocal.txt //查看原始文本,并未改动
#!/bin/sh # # This script will be executed *after* all the other init scripts. # You can put your own initialization stuff in here if you don't # want to do the full Sys V style init stuff. touch /var/lock/subsys/local
|
若希望直接修改文件内容,应添加选项"-i"。
比如,直接删除rcloal.txt文件的第1~4行,不输出结果:
1
2
3
4
|
[root@svr5 ~] # sed -i '1,4d' rclocal.txt //删除操作
[root@svr5 ~] # cat rclocal.txt //确认删除结果
# want to do the full Sys V style init stuff. touch /var/lock/subsys/local
|
3."-e"选项
选项"-e"用来指定一条“编辑指令”,实际上 -e 通常是被省略了;当需要执行多条编辑指令时,可添加多组 -e 操作。比如,输入/etc/rc.local文件的第1行、第4行,可以采用这种方式:
1
2
3
|
[root@svr5 ~] # sed -n -e '1p' -e '4p' /etc/rc.local
#!/bin/sh # You can put your own initialization stuff in here if you don't |
如果不使用"-e",也可以用分号来隔离多个操作(如果有定址条件,则应该使用{ }括起来),比如:
1
2
3
|
[root@svr5 ~] # sed -n '1p;4p' /etc/rc.local
#!/bin/sh # You can put your own initialization stuff in here if you don't |
或者:
1
2
3
|
[root@svr5 ~] # sed -n '{1p;4p}' /etc/rc.local
#!/bin/sh # You can put your own initialization stuff in here if you don't |
三、使用sed过滤文本示例:
1.先创建一个练习用的测试文件,每一行之前添加行号,方便练习时查看效果:
1
2
3
4
5
6
7
8
9
|
root@svr5 ~] # cat -n /etc/rc.local > 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)输出所有行,相当于cat命令。
1
2
3
4
5
6
7
8
|
[root@svr5 ~] # sed -n 'p' 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)输出第4行。
1
2
|
[root@svr5 ~] # sed -n '4p' rclocal.txt
4 # You can put your own initialization stuff in here if you don't
|
3)输出第4~7行。
1
2
3
4
5
|
[root@svr5 ~] # sed -n '4,7p' rclocal.txt
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)输出第4行和第7行。
1
2
3
|
[root@svr5 ~] # sed -n '4p;7p' rclocal.txt
4 # You can put your own initialization stuff in here if you don't
7 touch /var/lock/subsys/local
|
5)输出第2行及之后的3行。
1
2
3
4
5
|
[root@svr5 ~] # sed -n '2,+3p' rclocal.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.
|
6)输出以local结尾的行。
1
2
|
[root@svr5 ~] # sed -n '/local$/p' rclocal.txt
7 touch /var/lock/subsys/local
|
7)输出奇数行。
1
2
3
4
5
|
[root@svr5 ~] # sed -n 'p;n' rclocal.txt
1 #!/bin/sh
3 # This script will be executed *after* all the other init scripts.
5 # want to do the full Sys V style init stuff.
7 touch /var/lock/subsys/local
|
或者用:
1
|
#sed -n '1~2p' rclocal.txt |
8)输出偶数行。
1
2
3
4
|
[root@svr5 ~] # sed -n 'n;p' rclocal.txt
2 #
4 # You can put your own initialization stuff in here if you don't
6 |
或者用:
1
|
#sed -n '2~2p' rclocal.txt |
~(飘号):满几行输出多少行:比如1~2满2行输出第1行,2~2满2行输出第2行
9)从第5行输出到最后一行。
1
2
3
4
|
[root@svr5 ~] # sed -n '5,$p' rclocal.txt
5 # want to do the full Sys V style init stuff.
6 7 touch /var/lock/subsys/local
|
10)输出文本的行数。
1
2
|
[root@svr5 ~] # sed -n '$=' rclocal.txt
7 |
2.使用sed删除文本.
还以rclocal.txt文件为例,文件内容如下所示:
1
2
3
4
5
6
7
8
|
[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)删除第第3~5行文本
1
2
3
4
5
|
[root@svr5 ~] # sed '3,5d' rclocal.txt
1 #!/bin/sh
2 #
6 7 touch /var/lock/subsys/local
|
2)删除所有包含“init”的行。
1
2
3
4
5
|
[root@svr5 ~] # sed '/init/d' rclocal.txt
1 #!/bin/sh
2 #
6 7 touch /var/lock/subsys/local
|
3)删除所有包含“init”的行、所有包含“bin”的行。
1
2
3
4
|
[root@svr5 ~] # sed '/init/d;/bin/d' rclocal.txt
2 #
6 7 touch /var/lock/subsys/local
|
4)删除不包括“init”的行。
1
2
3
4
|
[root@svr5 ~] # sed '/init/!d' rclocal.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.
|
这个实际效果相当于只显示包含“init”的行:
6)删除文件中的空行
1
|
# sed '/^$/d' rclocal.txt |
手动添加2行空行到测试文件;清理重复空行,若连续两个空行只保留一个:
1
|
# sed '/^$/{n;/^$/d}' rclocal.txt |
3.使用sed实现字符串替换
-s:替换(跟vim vi编辑的时候的替换本质是一样的)
格式:
sed -i ‘【定址符】s/源数据/新数据/【选项】’ 文件列表
或者
命令 | sed ‘【定址符】s/源数据/新数据/【选项】’
多个文件列表之间用“空格”间隔
定址符:可选项,不指定逐行处理数据,可以使用正则表达式或行号
源字符:被替换的字符,可以用正则表达式匹配
新字符:替换后的字符
选项:g 全局替换 默认只替换第一个匹配的(global)
定址符正则的使用:
1
2
|
# sed ‘/[01]/s/bash/nologin/g’ a.txt // 把包含数字1和0的行中的 bash 换成nologin
|
当要替换的符号和间隔符号“/“重的时候可以自己替换间隔符号
1
|
# sed -r '1,10s;/sbin/nologin;/bin/bash;' sed.txt |
示例:还是以rclocal.txt文件为例
1)将所有行中的第一个“ll”(如果有的话)替换为“TARENA”。
1
2
3
4
5
6
7
8
|
[root@svr5 ~] # sed 's/ll/TARENA/' rclocal.txt
1 #!/bin/sh
2 #
3 # This script wiTARENA 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 fuTARENA Sys V style init stuff.
6 7 touch /var/lock/subsys/local
|
2)将所有的“ll”(如果有的话)替换为“TARENA”。
1
2
3
4
5
6
7
8
|
[root@svr5 ~] # sed 's/ll/TARENA/g' rclocal.txt
1 #!/bin/sh
2 #
3 # This script wiTARENA be executed *after* aTARENA the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the fuTARENA Sys V style init stuff.
6 7 touch /var/lock/subsys/local
|
3)将第3行内的第2个“script”替换为“SCRIPT”。
1
2
3
4
5
6
7
8
|
[root@svr5 ~] # sed '3s/script/SCRIPT/2' 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
|
*******s/源/目标/[选项] 这里的选项可以是g全局,也可以什么都不加,不加的时候默认替换第一个,也可以是数字N,数字的时候表示替换匹配的第N个******
4)删除文件内指定的字符串(替换为空)。
删除所有的“init”字符串:
1
2
3
4
5
6
7
8
|
[root@svr5 ~] # sed 's/init//g' rclocal.txt
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other scripts.
4 # You can put your own ialization stuff in here if you don't
5 # want to do the full Sys V style stuff.
6 7 touch /var/lock/subsys/local
|
删除所有的“script”、所有的“stuff”、所有的字母e,或者的关系用转义方式 \| 来表示:
1
2
3
4
5
6
7
8
|
[root@svr5 ~] # sed 's/script\|stuff\|e//g' rclocal.txt
.1 #!/bin/sh
2 #
3 # This will b xcutd *aftr* all th othr init s.
4 # You can put your own initialization in hr if you don't
5 # want to do th full Sys V styl init .
6 7 touch /var/lock/subsys/local
|
5)配置行的注释、解除注释。
解除/etc/rc.local文件第3~5行的注释(去掉开头的 # ):
1
2
3
4
5
6
7
|
[root@svr5 ~] # sed '3,5s/^#//' /etc/rc.local
#!/bin/sh # This script will be executed *after* all the other init scripts. You can put your own initialization stuff in here if you don't
want to do the full Sys V style init stuff.
touch /var/lock/subsys/local
|
去掉所有注释(行首去掉#):
1
|
[root@svr5 ~] # sed 's/^//' /etc/rc.local
|
把开头替换为空,即去掉所有注释;其实在vi vim 编辑器里也可以这么用
将/etc/rc.local文件的第6~7行注释掉(行首添加 # ):
1
|
[root@svr5 ~] # sed '6,7s/^/#/' /etc/rc.local
|
6)小括号的应用
修改IP地址的网段部分,主机地址不变。
直接修改网卡eth0的配置文件,检查原有的配置内容:
1
2
3
4
5
6
7
8
9
|
[root@svr5 ~] # cat /etc/sysconfig/network-scripts/ifcfg-eth0
# Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) DEVICE=eth0 BOOTPROTO=none HWADDR=00:0c:29:82:09:e9 ONBOOT= yes
NETMASK=255.255.255.0 IPADDR=192.168.4.4 TYPE=Ethernet |
若希望将IP地址192.168.4.4修改为172.16.16.4,则应该定位到“IPADDR”所在的行,执行相应的替换(仅测试,尚未修改):
1
2
3
|
[root@svr5 ~] # sed '/^IPADDR/s/192.168.4.4/172.16.16.4/' \
/etc/sysconfig/network-scripts/ifcfg-eth0 | grep "^IPADDR"
IPADDR=172.16.16.4 |
由于要求只修改网段地址,当上述操作在脚本中使用时,若要提供给不同的主机运行,显示不能直接写成 4 。这种情况下,可以利用扩展正则表达式的 \1、\2、……等调用,分别对应此前第1个、第2个、…… 以 ()包围的表达式所匹配的内容。
所以上述操作可以改为如下(启用扩展匹配应添加 -r 选项):
1
2
|
[root@svr5 ~] # sed -r -i '/^IPADDR/s/192.168.4.(.*)/172.16.16.\1/' \
/etc/sysconfig/network-scripts/ifcfg-eth0 |
遗忘回顾:
1、选项:-r:去掉正则表达式的转义符号和其他选项一起使用时放在首位
或者加转义符号 \
-e:指定多个处理动作,多个处理动作之间用分号;间隔
2、在替换的时候 s/源/目标/[选项] 这里的选项可以是g全局,也可以什么都不加,不加的时候默认替换第一个,也可以是数字N,数字的时候表示替换匹配的第N个
3、s替换可以参考s替换在vi vim编辑器中的用法。
本文转自Jx战壕 51CTO博客,原文链接:http://blog.51cto.com/xujpxm/1391845,如需转载请自行联系原作者