简介
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,20s/old/new/g,就代表把1~20行中的old替换成old
- 每个动作都可以与正则表达式配合,例如上面5点中说的
- 切记sed这个工具是以行为单位解析文本的