sed用法释疑

来源:互联网 发布:软件下载页面打不开 编辑:程序博客网 时间:2024/06/10 04:17

有点对不住这个标题了,本文仅仅讲一下自己在实践中遇到的一个问题,问题的原因,以及解决办法.而且这个问题可能有经验的人一眼就能看出来问题.至少知道调试排查.

很遗憾,我其实也知道,只是纠结了一个多小时才去调试.很多时候,我们缺少的仅仅是习惯而已.

首先说下问题,先看下面这个脚本.

<pre name="code" class="plain">#!/bin/bashif test $# -lt 1then    echo -e "uasge : must have a args\n"    exitfiif test ! -d $1then     echo -e "usage : must be dir\n"    exitfifor i in `ls $1/*.xml`do    sed -i "s/\(.*shell\).*\(\".*\)/\1\/$i\2/gp" test.xmldone
test.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?><test version="2.0.1">  <person name="alai" sex="nan" home="/home/alai/testspace/shell/sed/test.xml" /> </test>

这个脚本的意思是,找到另外一个文件夹下的文件,把test.xml文件中的sed/test.xml替换成其它文件夹中的xml文件.

如果这个脚本的sed语句单独运行,将$i替换成任何别的字符串比如alai.txt.都是没有问题的.如下:

但是在脚本中的运行结果则是这样的.

这个错误的意思是正则表达式里面的内容有问题.但是具体什么问题不得而知.

很惭愧的是,我走了很多弯路.刚开始以为sed访问shell变量有问题.查阅了一番资料以后发现没有问题.再后来又纠结版本不匹配.但是对于问题的解决都没有起到效果.

万般无奈之下,试了试sh -x.这个命令就是用调试的方式去执行shell脚本.

sh -x执行结果如下:

细心的同学可能已经看到了.在双引号里面出现了test/test.xml这样的语句.我们知道,shell是文本解释型的.也就是说他一边翻译每一句代码,一边执行它.当它翻译到出错的这句的时候.$i被展开了.成了test/test.xml . 而在这个表达式里面,/是有特殊意义的,它是作为分隔符存在的.

既然发现了问题的所在,那么解决起来就没那么麻烦了.

两种解决方式:

1. 杜绝在双引号中出现的/.修改后的脚本如下:

#!/bin/bashif test $# -lt 1then    echo -e "uasge : must have a args\n"    exitfiif test ! -d $1then     echo -e "usage : must be dir\n"    exitfifor i in `(cd $1;ls *.xml)`do    sed -n "s/\(.*shell\).*\(\".*\)/\1\/$1\/$i\2/gp" test.xmldone

2. 将分隔符替换成其它没有出现在表达式中的字符.如下:

#!/bin/bashif test $# -lt 1then    echo -e "uasge : must have a args\n"    exitfiif test ! -d $1then     echo -e "usage : must be dir\n"    exitfifor i in `ls $1/*.xml`do    sed -n "s+\(.*shell\).*\(\".*\)+\1\/$i\2+gp" test.xmldone

做个简短的结论吧.很庆幸我没有一味的借助于别人的帮助和网上的思路.貌似网上也没有类似的问题,可能太简单了.

无论这个问题对于别人而言如何,于我,这是一次思路的拓展.也希望我得文字能够带给同学们启发.

0 0
原创粉丝点击