linux 文件格式(1) sed工具

转载请出自出处:http://eksliang.iteye.com/blog/2106082

简介

      sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出或者加入-i参数。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

 

语法:

 

sed [-nefr] [动作]
参数说明:
-n:使用安静模式(silent)模式。在一般sed的用法中,所有来自stdin(标准输入)的数据
   一般都会被列出到屏幕上。但如果加上-n参数后,则只有经过sed特殊处理的那一行才会
   被显示(所以这个参数通常用在查看上 例如:sed -n '1,6p' /etc/passwd)
-e:直接在命令行模式上进行sed的动作编辑
-f:直接将sed的动作写在一个文件内,-f filename则可以执行filename内的sed动作
-r:sed的动作支持的是拓展型正则表达式的语法,但是默认是基础正则表达式的语法
-i:直接修改读取的文件内容,而不是由屏幕输出
动作说明:[n1[,n2]] function
n1,n2:这两个参数并不一定要存在,一般代表选择动作的行数,举例来说,如果我的动作
      是需要在10~20行之间进行,那么这个动作就是这么写'10,20[动作]'
function:function的取值如下:
a:新增,a的后面可以接字符串,而这些字符串会在新的一行出现(目前的下一行)
c:替换,c的后面可以接字符串,这些字符串可以替换n1、n2之间的行
d:删除,因为是删除,所有d后面通常不接任何参数
i:插入,i的后面可以接字符串,而这些字符串会在新的一行出现(目前的上一行)
p:打印,也就是将某个选择的数据打印在屏幕。通常会与参数 sed -n 一起运行
s:替换,可以直接进行替换。通常这个s的动作可以搭配正则表达式!

sed这个工具,光看是看不懂的,需要实际,像我一样,练习,跟我一起练习吧!

 

 

1、以行为单位的删除功能

 先复制一份/etc/passwd到测试目录如下:

[root@bogon shell]# cp /etc/passwd ./

 实例:将passwd的内容列出并且打印行号,同时,将2~5行删除

[root@bogon shell]# nl passwd | 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
     .....!

     sed '2,5d'这个 '2,5d'就是sed的动作,后面那个d就是删除。因为2~5行给他删除了,所以显示的数据就没有2~5行。sed后面的动作记得用单引号(')或者双引号(")括起来

     如果只删除第2行,怎么做?如下所示

    

[root@bogon shell]# nl passwd | sed '2d'
     1  root:x:0:0:root:/root:/bin/bash
     3  shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
     4  halt:x:7:0:halt:/sbin:/sbin/halt
.......!

   如果要删除第3行至最后一行怎么做?如下所示

[root@bogon shell]# nl passwd | sed '3,$d'
     1  root:x:0:0:root:/root:/bin/bash
     2  sync:x:5:0:sync:/sbin:/bin/sync

 那个"$"代表的是最后一行的意思!

 

2、添加功能

还是用复制过来的passwd这个文件测试

实例:在第二行后面加上"eksliang ni hao bang!" 如下所示

 

[root@bogon shell]# nl passwd | sed '2a eksliang ni hao bang!'
     1  root:x:0:0:root:/root:/bin/bash
     2  sync:x:5:0:sync:/sbin:/bin/sync
eksliang ni hao bang!
     3  shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
.......!

 实例:在第二行前面加上“eksliang ni hao bang!” 如下所示

 

[root@bogon shell]# nl passwd | sed '2i eksliang ni hao bang!'
     1  root:x:0:0:root:/root:/bin/bash
eksliang ni hao bang!
     2  sync:x:5:0:sync:/sbin:/bin/sync
......!

 

3、以行为单位的替换功能

实例:将passwd的2~5行替换成 “eksliang or ickes”

 

[root@bogon shell]# nl passwd | sed '2,5c eksliang or ickes'
     1  root:x:0:0:root:/root:/bin/bash
eksliang or ickes
     6  uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
.....

 部分数据的查找并替换的功能,这个可是个高档货,看仔细了!

sed的查找与替换跟vi编辑器相当类似,语法如下:

sed 's/要被替换的字符串/新的字符串/gw'
参数说明:
s:通知sed这是一个替换动作
w:将替换后的行输出到一个新文件

 下面通过寻找ip来演示一下,什么叫查找并替换吧!

步骤一:利用ipconfig 查询ip
[root@bogon shell]# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:0C:29:A6:32:02  
          inet addr:192.168.238.133  Bcast:192.168.238.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fea6:3202/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:9248 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3738 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:895349 (874.3 KiB)  TX bytes:529029 (516.6 KiB)
          Interrupt:19 Base address:0x2024 
步骤二:利用关键字配合grep选取出关键的一行数据
[root@bogon shell]# ifconfig eth0 | grep 'inet addr'
          inet addr:192.168.238.133  Bcast:192.168.238.255  Mask:255.255.255.0
步骤三:将ip前面的部分予以删除
[root@bogon shell]# ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g'
192.168.238.133  Bcast:192.168.238.255  Mask:255.255.255.0
#上面的删除,关键在于"s/^.*addr:"这个正则表达式
#含义是:将 inet addr:替换成空
步骤四:将ip后面的部分予以删除
[root@bogon shell]# ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g' | sed 's/Bcast:.*$//g'
192.168.238.133
#上面的删除(替换),关键在于Bcast:.*$这个正则表达式

    上面这个实例,也是我通过脚本操作复杂业务时的处理步骤。先查看,然后再一步一步试做,如果有做的不对的地方就予以修改,改完后在测试,然后继续循环,最后写出我准确的代码。

    如下实例演示w这个参数的作用,就是最后会把ip重定向到ip.txt这个文件

ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g' | sed 's/Bcast:.*$//gw ip.txt' 

 

4、通过sed这个命令来查看

查看是相当容易的,说多了都是扯淡,看实例

没有sed时,要列出11~20行的数据,最常用的就是如下命令组合:head -n 20 | tail -n 10

[root@bogon shell]# nl passwd | head -n 20 | tail -n 10
    11  nobody:x:99:99:Nobody:/:/sbin/nologin
    12  dbus:x:81:81:System message bus:/:/sbin/nologin
    13  usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
    14  vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
    15  rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin
    16  avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
    17  abrt:x:173:173::/etc/abrt:/sbin/nologin
    18  pulse:x:498:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
    19  haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
    20  saslauth:x:497:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin

 有了sed这个工具,当然不需要这样如下所示:

[root@bogon shell]# nl passwd | sed -n '11,20p'
    11  nobody:x:99:99:Nobody:/:/sbin/nologin
    12  dbus:x:81:81:System message bus:/:/sbin/nologin
    13  usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
    14  vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
    15  rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin
    16  avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
    17  abrt:x:173:173::/etc/abrt:/sbin/nologin
    18  pulse:x:498:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
    19  haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
    20  saslauth:x:497:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin

  上面这个实例加了“-n”这个参数,这个”-n“代表的是“安静模式”!如果没有这个-n你可以试下,取出的数据乱七八糟。

 

5、sed与正则表达式的结合使用这才叫做倍儿爽!

实例:将/etc/man.config这个文件中含有MAN字段的行取出,而且去掉#号的注释的行和空行

我还是按照上面3的那个步骤分析这个问题

步骤一:使用grep将含有'MAN'的行取出
[root@bogon shell]# cat /etc/man.config | grep 'MAN'
# when MANPATH contains an empty substring), to find out where the cat
# MANBIN                /usr/local/bin/man
.....!
# Every automatically generated MANPATH includes these fields
MANPATH /usr/man
MANPATH /usr/local/share/man
......!
步骤二:删除#号注释的行
[root@bogon shell]# cat /etc/man.config | grep 'MAN' | sed 's/#.*$//g'

......!

MANPATH /usr/man
MANPATH /usr/X11R6/man

......!

MANPATH_MAP     /bin                    /usr/share/man
MANPATH_MAP     /sbin                   /usr/share/man
.....!
步骤四:删除空行
[root@bogon shell]# 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
.....!

看到最后的删除空行没有,与正则表达式配合的语法如下:

sed '/正则表达式/动作'

 例如在passwd文件的每一行的后面都加上ickes

 

[root@bogon shell]# sed '/$/a ickes' passwd
root:x:0:0:root:/root:/bin/bash
ickes
sync:x:5:0:sync:/sbin:/bin/sync
ickes
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
ickes

 

 

6、加上-i直接修改文件内容,这个也倍儿爽

因为可以直接修改文件,这个时候就不用使用数据流重定向将修改的内容重新导向其他文件,但是也是一个危险的参数,建议不要使用这个命令去修改系统的配置文件

实例:将上面的man.config这个文件中以#开头和空行都删除(物理删除),但是我会将man.config这个文件拷贝出来,进行测试

shell script如下:

[root@bogon shell]# cat delete.sh 
#/bin/bash
sed -i 's/#.*$//g' man.config
sed -i '/^$/d'  man.config

 执行完后,查看man.config一定没有任何的注释和空行

 

总结如下:

  1.  每个动作前面都可以接数子例如:1,20s/old/new/g,就代表把1~20行中的old替换成old
  2. 每个动作都可以与正则表达式配合,例如上面5点中说的
  3. 切记sed这个工具是以行为单位解析文本的

 

 

      

 

你可能感兴趣的:(linux,linux sed工具,sed工具,linux sed详解)