linux下sed的使用(上)
介绍sed的使用,其中主要包括sed文本处理、文本块处理、sed的导入和导出。
简介:
sed全称是Stream EDdit,即流编辑器。他的特点如下:
--非交互,基于模式匹配的过滤及修改文本;
--逐行处理,并将结果输出到屏幕上;
--可实现对文本的输出、删除、替换、复制、剪切、导入、导出等各种操作;
--他有两个空间,模式空间和保持空间,主要在导入导出的时候着重讲解。
sed文本处理:
一、sed命令的基本用法
1)命令格式
格式1:前置命令 | sed [选项] '编辑指令'
格式2:sed [选项] '编辑指令' 文件.. ..
编辑指令说明如下:
其中,“编辑指令”用来实现过滤操作,由“[定址符]+处理动作”组成;
而“定址符”用来定义需要操作的文本,由“[地址1,[地址2]]组成,地址1为起始位置,地址2为结束位置;
未指定“定址符”时,默认处理所有文本;
只指定地址1时,只处理与地址1相匹配的文本。
二、sed常用选项解释:
-n :屏蔽输出源数据-i:直接对源文件进行操作-f:使用sed脚本,对文件进行处理-r:去掉正则表达式的转义符号和其他选项一起使用时放在首位 或者用转义符号 '\'-e:指定多个处理动作,多个处理动作之间用分号;间隔-p:打印输出-d:删除{}:可徐和多个命令组,以分号间隔
各选项使用示例:
1."-n"选项
执行p打印等过滤操作时,希望看到的是符合条件的文本。但不使用任何选项时,默认会将原始文本一并输出,从而干扰过滤效果。比如,尝试用sed输出/etc/rc.local的第1行,可以发现所有的行都被显示出来了:
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行了:
root@tbj:~# sed -n '1p' /etc/rc.local#!/bin/sh -e
而在执行删除等过滤操作时,希望看到的是删除符合条件的文本之后还能够被保留下来的文本,所以这时候就不应该使用"-n"选项了。比如,删除/etc/rc.local文件的第1-4行文本:
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命令所做的处理只是把操作结果(包括打印、删除等)输出到当前终端屏幕,而并不会对原始文件做任何更改:
[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行,不输出结果:
[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行,可以采用这种方式:
[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",也可以用分号来隔离多个操作(如果有定址条件,则应该使用{ }括起来),比如:
[root@svr5 ~]# sed -n '1p;4p' /etc/rc.local#!/bin/sh# You can put your own initialization stuff in here if you don't
或者:
[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.先创建一个练习用的测试文件,每一行之前添加行号,方便练习时查看效果:
root@svr5 ~]# cat -n /etc/rc.local > rclocal.txt[root@svr5 ~]# cat rclocal.txt1 #!/bin/sh2 #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't5 # want to do the full Sys V style init stuff.67 touch /var/lock/subsys/local
1)输出所有行,相当于cat命令。
[root@svr5 ~]# sed -n 'p' rclocal.txt1 #!/bin/sh2 #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't5 # want to do the full Sys V style init stuff.67 touch /var/lock/subsys/local
2)输出第4行。
[root@svr5 ~]# sed -n '4p' rclocal.txt4 # You can put your own initialization stuff in here if you don't
3)输出第4~7行。
[root@svr5 ~]# sed -n '4,7p' rclocal.txt4 # You can put your own initialization stuff in here if you don't5 # want to do the full Sys V style init stuff.67 touch /var/lock/subsys/local
4)输出第4行和第7行。
[root@svr5 ~]# sed -n '4p;7p' rclocal.txt4 # You can put your own initialization stuff in here if you don't7 touch /var/lock/subsys/local
5)输出第2行及之后的3行。
[root@svr5 ~]# sed -n '2,+3p' rclocal.txt2 #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't5 # want to do the full Sys V style init stuff.
6)输出以local结尾的行。
[root@svr5 ~]# sed -n '/local$/p' rclocal.txt7 touch /var/lock/subsys/local
7)输出奇数行。
[root@svr5 ~]# sed -n 'p;n' rclocal.txt1 #!/bin/sh3 # 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
或者用:
#sed -n '1~2p' rclocal.txt
8)输出偶数行。
[root@svr5 ~]# sed -n 'n;p' rclocal.txt2 #4 # You can put your own initialization stuff in here if you don't6
或者用:
#sed -n '2~2p' rclocal.txt
~(飘号):满几行输出多少行:比如1~2满2行输出第1行,2~2满2行输出第2行
9)从第5行输出到最后一行。
[root@svr5 ~]# sed -n '5,$p' rclocal.txt5 # want to do the full Sys V style init stuff.67 touch /var/lock/subsys/local
10)输出文本的行数。
[root@svr5 ~]# sed -n '$=' rclocal.txt7
2.使用sed删除文本.
还以rclocal.txt文件为例,文件内容如下所示:
[root@svr5 ~]# cat rclocal.txt1 #!/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't5 # want to do the full Sys V style init stuff.67 touch /var/lock/subsys/local
1)删除第第3~5行文本
[root@svr5 ~]# sed '3,5d' rclocal.txt1 #!/bin/sh2 #67 touch /var/lock/subsys/local
2)删除所有包含“init”的行。
[root@svr5 ~]# sed '/init/d' rclocal.txt1 #!/bin/sh2 #67 touch /var/lock/subsys/local
3)删除所有包含“init”的行、所有包含“bin”的行。
[root@svr5 ~]# sed '/init/d;/bin/d' rclocal.txt2 #67 touch /var/lock/subsys/local
4)删除不包括“init”的行。
[root@svr5 ~]# sed '/init/!d' rclocal.txt3 # This script will be executed *after* all the other init scripts.4 # You can put your own initialization stuff in here if you don't5 # want to do the full Sys V style init stuff.
这个实际效果相当于只显示包含“init”的行:
6)删除文件中的空行
# sed '/^$/d' rclocal.txt
手动添加2行空行到测试文件;清理重复空行,若连续两个空行只保留一个:
# sed '/^$/{n;/^$/d}' rclocal.txt
3.使用sed实现字符串替换
-s:替换(跟vim vi编辑的时候的替换本质是一样的)
格式:
sed -i ‘【定址符】s/源数据/新数据/【选项】’ 文件列表
或者
命令 | sed ‘【定址符】s/源数据/新数据/【选项】’
多个文件列表之间用“空格”间隔
定址符:可选项,不指定逐行处理数据,可以使用正则表达式或行号
源字符:被替换的字符,可以用正则表达式匹配
新字符:替换后的字符
选项:g 全局替换 默认只替换第一个匹配的(global)
定址符正则的使用:
# sed ‘/[01]/s/bash/nologin/g’ a.txt//把包含数字1和0的行中的bash换成nologin
当要替换的符号和间隔符号“/“重的时候可以自己替换间隔符号
# sed -r '1,10s;/sbin/nologin;/bin/bash;' sed.txt
示例:还是以rclocal.txt文件为例
1)将所有行中的第一个“ll”(如果有的话)替换为“TARENA”。
[root@svr5 ~]# sed 's/ll/TARENA/' rclocal.txt1 #!/bin/sh2 #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't5 # want to do the fuTARENA Sys V style init stuff.67 touch /var/lock/subsys/local
2)将所有的“ll”(如果有的话)替换为“TARENA”。
[root@svr5 ~]# sed 's/ll/TARENA/g' rclocal.txt1 #!/bin/sh2 #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't5 # want to do the fuTARENA Sys V style init stuff.67 touch /var/lock/subsys/local
3)将第3行内的第2个“script”替换为“SCRIPT”。
[root@svr5 ~]# sed '3s/script/SCRIPT/2' rclocal.txt1 #!/bin/sh2 #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't5 # want to do the full Sys V style init stuff.67 touch /var/lock/subsys/local
*******s/源/目标/[选项] 这里的选项可以是g全局,也可以什么都不加,不加的时候默认替换第一个,也可以是数字N,数字的时候表示替换匹配的第N个******
4)删除文件内指定的字符串(替换为空)。
删除所有的“init”字符串:
[root@svr5 ~]# sed 's/init//g' rclocal.txt1 #!/bin/sh2 #3 # This script will be executed *after* all the other scripts.4 # You can put your own ialization stuff in here if you don't5 # want to do the full Sys V style stuff.67 touch /var/lock/subsys/local
删除所有的“script”、所有的“stuff”、所有的字母e,或者的关系用转义方式 \| 来表示:
[root@svr5 ~]# sed 's/script\|stuff\|e//g' rclocal.txt.1 #!/bin/sh2 #3 # This will b xcutd *aftr* all th othr init s.4 # You can put your own initialization in hr if you don't5 # want to do th full Sys V styl init .67 touch /var/lock/subsys/local
5)配置行的注释、解除注释。
解除/etc/rc.local文件第3~5行的注释(去掉开头的 # ):
[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'twant to do the full Sys V style init stuff.touch /var/lock/subsys/local
去掉所有注释(行首去掉#):
[root@svr5 ~]# sed 's/^//' /etc/rc.local
把开头替换为空,即去掉所有注释;其实在vi vim 编辑器里也可以这么用
将/etc/rc.local文件的第6~7行注释掉(行首添加 # ):
[root@svr5 ~]# sed '6,7s/^/#/' /etc/rc.local
6)小括号的应用
修改IP地址的网段部分,主机地址不变。
直接修改网卡eth0的配置文件,检查原有的配置内容:
[root@svr5 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0# Intel Corporation 82545EM Gigabit Ethernet Controller (Copper)DEVICE=eth0BOOTPROTO=noneHWADDR=00:0c:29:82:09:e9ONBOOT=yesNETMASK=255.255.255.0IPADDR=192.168.4.4TYPE=Ethernet
若希望将IP地址192.168.4.4修改为172.16.16.4,则应该定位到“IPADDR”所在的行,执行相应的替换(仅测试,尚未修改):
[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 选项):
[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编辑器中的用法。