sed命令的使用必须配合正则表达式的,sed本省也是一个管道命令,可以分析standard input,也可以用来进行数据的替换、新增、选取特定行的功能。
sed参数:
- -n:使用安静模式,在sed的一般用法中,所有来自stdin 的数据都会被列出在屏幕上,如果加上了-n参数,则只有经过处理过的那一行才会被列出来。
- -e:直接在命令行模式下进行sed的编辑操作。
- -f:直接将sed的动作写在一个文件内,-f filename则可以执行filename内的左右的sed动作。
- -r:支持扩展的正则表达式。
- -i:直接修改文件的内容,而不是由屏幕输出。
常见动作:
a:新增,a后面接的是字符串,这些字符串会在下一行出现。
c:替换,c之后的字符串将会替换规定行之间的所有的行。
d:删除,删除指定的行。
i:插入,在指定行的前面进行插入。
p:打印,将某个选择的数据打印出来。
s:替换,与正则表达式搭配比较多。
练习:
一、删除/etc/passwd下面的2,7行:
[root@minion-1 ~]# cat -n /etc/passwd | sed '2,7d'
1 root:x:0:0:root:/root:/bin/bash
**被删除的部分**
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
11 games:x:12:100:games:/usr/games:/sbin/nologin
12 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
同理,如果只删除第二行:nl /etc/passwd | sed '2d'
删除第7行到末尾:[root@minion-1 ~]# nl /etc/passwd | sed '7,$d'
二、添加。在第8行下面添加‘this is sed’s add’;
[root@minion-1 ~]# nl /etc/passwd | sed "8a This is sed's add"
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
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
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
This is sed's add
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
同理,添加在第8行之前:nl /etc/passwd | sed "8i This is sed's add"
若是添加两行怎么办?[root@minion-1 ~]# nl /etc/passwd | sed "8i This is sed's add \\ more raw ...."
只需要在每一行的分割间使用\即可!简单吧。
三、替换与显示:将3~10行内容替换为‘This is sed’s change’
[root@minion-1 ~]# nl /etc/passwd | sed "3,10c This is sed\'s change."
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
This is sed's change.
11 games:x:12:100:games:/usr/games:/sbin/nologin
再来看sed的一个很有趣的用法:加入我只想查看/etc/passwd下面的5~7行,你会不会想到那就使用一个p动作就可以了呢?先来看看:
[root@minion-1 ~]# nl /etc/passwd | sed '5,7p'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
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
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
你肯定会非常惊讶,怎么打印了那么多?而且5~7行数据还给我打印了两遍,这时是需要加上-n参数的,-n参数表示不被选择的数据行是不会被输出的。再来看:
[root@minion-1 ~]# nl /etc/passwd | 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
四、部分数据的查找以及替换
这时就需要使用到正则表达式。
先来看看正则表达式的几个基本的字符:
- ^word:表示是以word开头的字符串
- word$:表示以word结尾的字符串
- .:任意的一个字符。
- *:前一个字符0到无穷多个。
- :转移符
- [list]:包含list中的任何一个字符。
- [n1-n2]:查找字符范围。
- [^list]:除list之外的字符。
- \{n,m\}:连续的n到m个前一个字符。
- [a-z]:小写字母
- [A-Z]:大写字母
- [0-9]:数字。等
sed 's/要被替换的字符/新的字符串/g'
使用sed获取ifconfig中的ip地址:
第一步:
[root@minion-1 ~]# ifconfig | grep "inet[^6]"
inet 192.168.0.103 netmask 255.255.255.0 broadcast 192.168.0.255
inet 127.0.0.1 netmask 255.0.0.0
上面的grep "inet[^6]"就代表行中存在inet但其后不是6.
第二步:
[root@minion-1 ~]# ifconfig | grep "inet[^6]"| sed 's/^.*inet //g' | sed 's/[[:space:]].*//g'
192.168.0.103
127.0.0.1
即可!
五、直接修改文件:
如果说一个文件有100多万行,需要在第100行下添加一句,那么使用vim 将会是十分麻烦的。那么-i参数将会非常方便。