SED坏替换错误

时间:2011-08-23 08:02:15

标签: bash shell sed

这是我的问题,我编写了以下代码行来正确格式化在目录中递归发现的文件列表。

find * | sed -e '/\(.*\..*\)/ !d' | sed -e "s/^.*/\${File} \${INST\_FILES} &/" | sed -e "s/\( \)\([a-zA-Z0-9]*\/\)/\/\2/" | sed -e "s/\(\/\)\([a-zA-Z0-9\_\-\(\)\{\}\$]*\.[a-zA-Z0-9]*\)/ \2/"

第二步是在脚本中写入此命令的输出。虽然上面的代码具有预期的行为,但当我尝试将其输出存储到变量时会出现问题,我从行中的第一个sed命令得到一个错误的替换错误。

#!/bin/bash
nsisscript=myscript.sh
FILES=*
for f in $(find $FILES); do 
v=`echo $f | sed -e '/\(.*\..*\)/ !d' | sed -e "s/^.*/\${File} \${INST\_FILES} &/" | sed -e "s/\( \)\([a-zA-Z0-9]*\/\)/\/\2/" | sed -e "s/\(\/\)\([a-zA-Z0-9\_\-\(\)\{\}\$]*\.[a-zA-Z0-9]*\)/ \2/"`
sed -i.backup -e "s/\;Insert files here/$v\\n&/" $nsisscript 
done 

请您帮我理解这两种情况之间的区别以及为什么会出现此错误?

提前致谢!

2 个答案:

答案 0 :(得分:0)

我的猜测是你在INST_FILES中转义下划线很奇怪,因为下划线不是shell中的特殊字符,也不是sed中的特殊字符。删除'_'

之前的'\'时,错误消失 我的2美分

答案 1 :(得分:0)

在反引号式命令替换中解析有点奇怪 - 它需要额外的转义级别(即反斜杠)来控制何时进行扩展。丑陋的解决方案:添加更多反斜杠。更好的解决方案:使用$()而不是反引号 - 它做同样的事情,但没有奇怪的解析和转义问题。

顺便说一句,你的脚本似乎还有其他一些问题。首先,我不知道你系统上的sed,但是我熟悉的版本不会将替换中的\n解释为换行符(我认为你想要的),但是作为文字n字符。一种解决方案是在替换中包含一个文字换行符(前面加一个反斜杠)。

此外,循环对每个找到的文件执行,但对于名称中没有句点的文件,第一个sed命令将删除它们,$v为空,并添加空白行到myscript.sh。您应该将过滤sed调用放在for语句中,或将其作为过滤器添加到find命令中。

#!/bin/bash
nsisscript=myscript.sh
nl=$'\n'
FILES=*
for f in $(find $FILES -name "*.*"); do 
    v=$(echo $f | sed -e "s/^.*/\${File} \${INST\_FILES} &/" | sed -e "s/\( \)\([a-zA-Z0-9]*\/\)/\/\2/" | sed -e "s/\(\/\)\([a-zA-Z0-9\_\-\(\)\{\}\$]*\.[a-zA-Z0-9]*\)/ \2/")
    sed -i.backup -e "s/\;Insert files here/$v\\$nl&/" $nsisscript 
done