浅谈Sed的用法

sed的用法

sed是Linux/Unix平台下的轻量级流量编辑器,日常一般用于处理文本文件。sed有许多很好的特性。
首先,它相当小巧;其次,sed可以配合强大的Shell来完成许多复杂的功能。
Sed完全可以被看成一个脚本解释器,它用类似于编程的手段完成许多事情。我们完全可以用Vim+Sed的方式来处理日常工作中的大多数文档。
 
1. Sed的基础语法格式
Sed的格式如下所示:
sed [-nefr] [n1,n2] action
其中:
a.-n: 是安静模式,只有经过sed处理过的行才显示出来,其他不显示。
b.-e: 表示直接在命令行模式上进行Sed的操作。是默认选项,不用写。
c.-f: 将sed的操作写一个文件里,用的时候-f filename就可以按照内容进行Sed操作了。
d.-r: 表示使用Sed支持扩展正则表达式。
e.n1,n2: 不一定需要,选择要进行处理的行。如:10,20表示在10~20行,之间处理。

Sed的action(动作)支持如下参数。
@ a: 表示添加,后接字符串,添加到当前行的下一行。
@ c: 表示替换,后接字符串,用它替换n1到n2之间的行。
@ d: 表示删除符合模式的行,它的语法为sed '/regexp/'d,斜杠之间是正则表达式,模式在d前面,d后面一般不接任何内容。
@ i: 表示插入,后接字符串,添加到当前行的上一行。
@ p: 表示打印,打印某个选择的数据,通常与-n安静模式一起使用。
@ s: 表示搜索,还可以替换,类似于vim里的搜索替换功能。例如:1,20s/old/new/g表示替换1~20行的old为new,g在这里表示处理这一行所有匹配的内容。(这里的/也可以是其他字符,如@、#等,但不能用$^等字符)
 
在这里要注意一下:动作最好用''括起来,防止空格导致错误
 
Sed实例如下所示:
1)显示passwd内容,将2~5行删除后显示
# cp /etc/passwd zhou
(先复制一份出来,免得误操作)
cat -n zhou | sed '2,5d'
 
     1 root:x:0:0:root:/root:/bin/bash
     6 sync:x:5:0:sync:/sbin:/bin/sync
     7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
     8 halt:x:7:0:halt:/sbin:/sbin/halt
     9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
2)在第2行后面一行加上Hell China字符串。
cat -n zhou | sed '2a Hell China'
     1 root:x:0:0:root:/root:/bin/bash
     2 bin:x:1:1:bin:/bin:/sbin/nologin
Hell China
     3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4 adm:x:3:4:adm:/var/adm:/sbin/nologin
     5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     6 sync:x:5:0:sync:/sbin:/bin/sync
3)在第2行后面加上两行字,例如:"this is first line!" 和"This is second line!"
cat -n zhou | sed '2a this is first line!\   //使用续航符\后按回车输入后续行
> This is second line!'                      //以'再回车结束
     1 root:x:0:0:root:/root:/bin/bash
     2 bin:x:1:1:bin:/bin:/sbin/nologin
this is first line!
This is second line!
     3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4 adm:x:3:4:adm:/var/adm:/sbin/nologin
4)将2~5行的内容替换成 "我是大好人!"
cat -n zhou | sed '2,5c 我是大好人.'
     1 root:x:0:0:root:/root:/bin/bash
我是大好人
     6 sync:x:5:0:sync:/sbin:/bin/sync
     7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
5)只显示5~7行,注意p与-n的配合使用!
cat -n zhou | sed -n '5,7p'
     5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     6 sync:x:5:0:sync:/sbin:/bin/sync
     7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
 
6)使用ifconfig列出ip,我们只想要eth0的ip地址。可以先用grep取出有ip的那一行,然后用sed来去掉(替换成空)ip前面和后面的内容,如下所示:
ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:0C:29:00:9C:77  
          inet addr:192.168.1.195  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe00:9c77/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:138728 errors:0 dropped:0 overruns:0 frame:0
          TX packets:11652 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:11968733 (11.4 MiB)  TX bytes:1850068 (1.7 MiB)
          Interrupt:59 Base address:0x2000 
 
ifconfig eth0 | grep 'inet addr' | sed 's/^.* addr://g' | sed 's/Bcast.*$//g'
192.168.1.195
'^.* addr:' 表示从开头到addr:的字符串,将它替换成空,'Bcast.*$'表示从Bcast到结尾的字符串也将它替换成空,然后就只剩下ip了。
别外一种更简单的方法如下:
ifconfig eth0 | grep 'inet addr:' | awk -F[:" "]+ '{print $4}'
awk -F[:" "]的意思就是以:或空格符作为分隔符,然后打印出第4例
7)在/etc/man.config中,将有MAN的设置取出,但不要说明内容。代码如下所示:
cat /etc/man.config | grep 'MAN'| sed 's/#.*$//g' | sed '/^$/'d
MANPATH /usr/man
MANPATH /usr/share/man
MANPATH /usr/local/man
MANPATH /usr/local/share/man
MANPATH /usr/X11R6/man
MANPATH_MAP /bin /usr/share/man
MANPATH_MAP /sbin /usr/share/man
MANPATH_MAP /usr/bin /usr/share/man
MANPATH_MAP /usr/sbin /usr/share/man
MANPATH_MAP /usr/local/bin /usr/local/share/man
 
 
注意,#不一定出现在行首。因此,/#.*$/表示#后面的数据(直到行尾)是一行注释,将它们替换成空。/^$/表示空行,后接d表示删除空行。注意,删除空行不能用替换方法,因为空行替换成空后,还有换行符在那一行中。
 
 
以上就是sed的几种常见的语法命令。
 
2.Sed的用法举例说明
 
a.sed的基础用法
1)删除行首空格,代码如下:
sed 's/^[ ]*//g' filename
sed 's/^*//g' filename
sed 's/^[[:space:]]*//g' filename
 
cat zhou.txt 
zhou lishan is good man
 
 
   zhou lishan
 lishan zhou
ls ls ls 
  fir fie ds
 
  ###
###################
     ((((((((((((((((((((((((
 
sed 's/^[ ]*//g' zhou.txt
zhou lishan is good man
 
 
zhou lishan
lishan zhou
ls ls ls 
fir fie ds
 
###
###################
((((((((((((((((((((((((
2)在行后和行前添加新行
@a.在行后的命令如下:
sed 's/pattern/&\\n/g' filename
 
sed 's/ls ls ls/& nahsil uohz/g' zhou.txt 
zhou lishan is good man
 
 
   zhou lishan
 lishan zhou
ls ls ls nahsil uohz 
  fir fie ds
@b.在行前的命令如下:
sed 's/pattern/\\n&/g' filename
 
sed 's/ls ls ls/nahsil uohz &/g' zhou.txt 
zhou lishan is good man
 
 
   zhou lishan
 lishan zhou
nahsil uohz ls ls ls 
  fir fie ds
 
其中,&代表pattern
 
3)使用变量替换(使用双引号),代码如下:
sed -e "s/$var1/$var2/g" filename
4)在第一行前插入文本,代码如下:
sed '1 i\\插入字符串' filename
 
sed '1 i 插入字符串' zhou.txt
插字符串
zhou lishan is good man
 
5)在最后一行插入文本,代码如下:
sed '$a \\插入字符串' filename
 
sed '$a 插字符串' zhou.txt
zhou lishan is good man
 
 
   zhou lishan
 lishan zhou
ls ls ls 
  fir fie ds
 
  ###
###################
     ((((((((((((((((((((((((
插字符串
 
 
6)在匹配行前插入,代码如下:
sed '/pattern/i "插入字符串"' filename
 
sed '/zhou/i "插入字符串"' zhou.txt 
"插入字符串"
zhou lishan is good man
 
 
"插入字符串"
   zhou lishan
"插入字符串"
 lishan zhou
ls ls ls 
  fir fie ds
7)在匹配行后插入,代码如下:
sed '/pattern/a "插入字符串" filename
 
sed '/zhou/a "插入字符串"' zhou.txt 
zhou lishan is good man
"插入字符串"
 
 
   zhou lishan
"插入字符串"
 lishan zhou
"插入字符串"
 
 
8)删除文本中空行和空格组成的行及#号注释的行,代码如下:
 
grep -v ^# filename | sed /^[[:space:]]*$/d | sed /^[[:space:]].*$/d
 
grep -v ^# zhou.txt | sed /^[[:space:]]*$/d | sed /^[[:space:]].*$/d
zhou lishan is good man
ls ls ls 
[root@localhost sed]# cat zhou.txt
zhou lishan is good man
 
 
   zhou lishan
 lishan zhou
ls ls ls 
  fir fie ds
 
  ###
###################
     ((((((((((((((((((((((((
 
 
9)要将目录/modlules下面所有文件中的zhangsan都修改成list,可用如下命令(要先备份哟),代码如下:
sed 's/zhangsan/list/g' 'grep zhangsan -rl /modules'
 
 
Vim + Sed
在Vim里删除所有行的首数字,命令如下:
:%s/^[0-9][0-9]*//g
再删除所有行的首空字符,如下所示
sed -i 's/^[[:space:]]*//g' filename
 
 
Sed 结合正则表达式批量修改文件
比如要修改test.txt文件中的地址为
cat test.txt 
http://www.cjdao.com/produce/2007080412/315613171.shtml
http://bz.cjdao.com/produce/20080808/311217.shtml
http://gz.cjdao.com/produce/2009/0909/311412.shtml
 
要求把http://*.cjdao.com更改为/home/html/www.cjdao.com。我们可以利用sed正则表达式解决,如下所示
sed 's@http.*\.com@\/home/\/html\/www.cjdao.com@g' test.txt
/home/html/www.cjdao.com/produce/2007080412/315613171.shtml
/home/html/www.cjdao.com/produce/20080808/311217.shtml
/home/html/www.cjdao.com/produce/2009/0909/311412.shtml
 
在配置.conf文件时,经常要为相邻的几行添加#号以注释掉
 
例如,要将test.txt文件中的31~36行加上#号
在vim中,我们可以执行如下代码:
:31,36 s/^/#/
 
而用sed的话则执行起来更方便,如下所示:
sed '31,36s/^/#/' test.txt
 
也有人会习惯在这个方法后面带个g,事实上,如果没有g,则表示从行的左端开始匹配,每一行第一个与之匹配的会被换掉;如果有g,则表示每一行所有与之匹配的都会被替换。
 
 
利用Sed很方便地分析日志
利用sed还可以很方便的分析日志,
例如:
cat /var/log/secure | sed -n '/12:48:48/,/12:48:55/p'
 
 
 
 
关于sed的使用方法就先介绍到这里,要想运用好sed以及awk要必须先学习正则表达式。

 

你可能感兴趣的:(正则表达式,sed用法)