今天编写shell程序时遇到了一个关于sed命令的问题。问题简化如下。
文本文件1.txt中包含字符串[:50]
~/Documents/books/linux/test$:cat 1.txt愿意想将[:50]替换为[50:100],脚本如下:
[:50]
~/Documents/books/linux/test$:cat test.sh #!/bin/basholdstr="[:50]"newstr="[50:100]"cat 1.txt | sed -n 's/$oldstr/$newstr/p'运行./test.sh,结果没有输出
~/Documents/books/linux/test$:./test.sh ~/Documents/books/linux/test$:于是,我上网查找问题原因,
1,如何在sed里使用变量的问题,发现原来是双引号和单引号引用的区别。
单引号:shell处理命令时,对其中的内容不做任何处理。即此时是引号内的内容是sed命令所定义的格式。
双引号:shell处理命令时,要对其中的内容进行算术扩展。如果想让shell扩展后得到sed命令所要的格式
下面是个简单的例子
~/Documents/books/linux/test$:name=chen网上总结了四种方案
~/Documents/books/linux/test$:echo '$name' # $当作字符处理
$name
~/Documents/books/linux/test$:echo "$name" # $作为特殊字符处理
chen
1. eval sed 's/$a/$b/' filename
2. sed "s/$a/$b/" filename
3. sed 's/'$a'/'$b'/' filename
4. sed s/$a/$b/ filename
于是我将脚本中sed中的单引号改为双引号。
#!/bin/bash但是输出的结果却跟预想的不一样。结果如下:
oldstr="[:50]"
newstr="[50:100]"
cat 1.txt | sed -n "s/$oldstr/$newstr/p"
~/Documents/books/linux/test$:./test.sh [[50:100]50]
正则表达式认可的特殊字符有:
. * [ ] ^ $ { } \ + ? | ( )
这些特殊字符中的一个作为文本字符,需要在特殊字符前添加反斜杠字符\ 来转义它。
得到之前的结果是因为sed中的正则表达式[:50]表示第一个匹配: , 5,0任一字符用[50:100]进行替换。字符串[:50]第一个匹配的是:,所以得到[[50:100]50].所以我将oldstr中的[]进行转义,并且在sed命令选项中加上g进行完全替换。
#!/bin/bash则得到我想要的结果:
oldstr="\[:50\]"
newstr="[50:100]"
cat 1.txt | sed -n "s/$oldstr/$newstr/g;p"
~/Documents/books/linux/test$:./test.sh问题解决完毕。
[50:100]