我是seder,不是awker
一、命令格式:
sed [范围] [sy] [表达式] [命令]
如命令
sed ‘1,5s/haha/hehe/g’ inputfile
将文件input的1至5行中的所有haha变为hehe,并输出到控制台
二、处理流程
sed命令处理流程大致是这样子:
1.输入文件(或管道)一行一行地 进入“模式空间”
2.在“模式空间”里,sed一行一行地处理数据
3.数据完的数据一行一行地输出到文件或标准输出
有图有真相
三、示例
1.“或”条件查询
grep "SEEK_MYSELF" -rn * | sed '/tags\|\(Binary\)/d'
| ( ) 都属于正则表达式的POSIX扩展, 在sed里不直接支持 需要加转义字符\ 。
也就是说得这样使用: expr\|\(expr\)
同理,vim 中也这样使用“或”正则表达式来查询行
同理,grep中也这样使用“或”
[root@local ~]# grep "dmr\|\(hwdata\)" install.log
grep搜文件,连续5个小写字母相连
[root@local ~]# grep "\([a-z]\)\1\1\1\1" aa.txt
[root@local ~]# grep '\([a-z]\)\1\{4\}' aa.txt
2.“且”条件查询
正则表达式只有“或”,没有“且”,所以只能“曲线救国”
vim 中这样使用“且”正则表达式来查询行
同理,sed中使用“且”
[root@local ~]# sed -n '/leon.*hui\|\(hui.*leon\)/p' test
同理,grep中也这样使用“且”
[root@local ~]# grep "leon.*hui\|\(hui.*leon\)" test
PS:
[root@local ~]# grep "leon.*hui\|\(hui.*leon\)" test
huileonkelly
lfksjdfskleonsdfsdhui
[root@local ~]# grep -e "leon.*hui\|hui.*leon" test
huileonkelly
lfksjdfskleonsdfsdhui
[root@local ~]# grep -E "leon.*hui|hui.*leon" test
huileonkelly
lfksjdfskleonsdfsdhui
这有一个麻烦,若patten有n个,那你再 就得写 n! 种情景。。。。
n 大于2 的时候,不得不用 grep | grep | grep ???
3.cvs up时,只显示有更改的行
cvs up 2>&1 | sed '/^cvs/d
4.批量修改文件
网管部规范了CVS,要使用新的CVS账号密码
我一提交内核代码,傻眼了:代码是老账号co下来的,提交时用的还是老账号,提交失败
看了一下问题出在每个目录下面 CVS/Root 里有:
:ext:tester@192.168.1.130:/ljscm/cvsroot
把tester改为新账号leon即可
co下来的内核代码里,CVS/Root文件太多了,用如下命令批量修改
sed -i 's/tester/leon/g' `find . -name "Root"`
5.获取IP地址
[root]# cat test
[root]# sed -e 's/[^\/]*\/\/\([^\/]*\).*/\1/' test
6.贪婪法则 shell 正则表达式为 贪婪的(greedy)
[root]# cat test1
uid=500(guest) gid=500(others) groups=500(users),11(floppy)
下面把小括号内的值单独取出,如果利用贪婪规则,解决方案如下:
sed -e 's/[^(]*(\([^)]*\).*/\1/' test1
sed -e 's/[^(]*(\([^)]*\)[^(]*(\([^)]*\).*/\2/' test1
sed -e 's/[^(]*(\([^)]*\)[^(]*(\([^)]*\)[^(]*(\([^)]*\).*/\3/' test1
sed -e 's/.*(\(.*\))/\1/' test1
上面四条命令分别可以获得括号内的数值。如果是不利用贪婪规则,还有其他的解决方案:
//利用sed和awk
[root]# sed -e 's/[()]/:/g' test1 | awk -F: '{ print $2 }' # guest
[root]# sed -e 's/[()]/:/g' test1 | awk -F: '{ print $4 }' # others
[root]# sed -e 's/[()]/:/g' test1 | awk -F: '{ print $6 }' # users
[root]# sed -e 's/[()]/:/g' test1 | awk -F: '{ print $8 }' # floppy
//利用tr和cut
[root]# tr "()" ':' < test1 | cut -d: -f2 #guest
[root]# tr "()" ':' < test1 | cut -d: -f4 #others
[root]# tr "()" ':' < test1 | cut -d: -f6 #users
[root]# tr "()" ':' < test1 | cut -d: -f8 #floppy
目标是分别取出2008和2009两部分,利用贪婪规则如下:
[root]# cat test
aaa:2008
aaa:2009
[root]#sed -e 's/.*:\([^<]*\).*/\1/' test # 得 2009
[root]#sed -e 's/[^:]*:\([^<]*\).*/\1/' test # 得 2008
阅读(1863) | 评论(0) | 转发(0) |