SED 坏替换错误 [英] SED bad substitution error
问题描述
这是我的问题,我编写了以下代码行来正确格式化在目录中递归找到的文件列表.
Here's my problem, I have written the following line of code to format properly a list of files found recursively in a directory.
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 命令中得到一个错误的替换错误.
The second step is to write the output of this command in a script. While the code above has the expected behavior, the problem occurs when I try to store its output to a variable, I get a bad substitution error from the first sed command in the line.
#!/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
能否请您帮我理解这两种情况之间的区别以及为什么会出现此错误?
Could you please help me understand what the difference is between the two cases and why I get this error ?
提前致谢!
推荐答案
反引号样式命令替换内部的解析有点奇怪——它需要额外的转义级别(即反斜杠)来控制何时进行扩展.丑陋的解决方案:添加更多反斜杠.更好的解决方案:使用 $()
而不是反引号——它做同样的事情,但没有奇怪的解析和转义问题.
Parsing inside of backquote-style command substitution is a bit weird -- it requires an extra level of escaping (i.e. backslashes) to control when expansions take place. Ugly solution: add more backslashes. Better solution: use $()
instead of backquotes -- it does the same thing, but without the weird parsing and escaping issues.
顺便说一句,您的脚本似乎还有一些其他问题.首先,我不知道您系统上的 sed
,但我熟悉的版本不会将替换中的 \n
解释为换行符(即我想你想要),但作为文字 n
字符.一种解决方案是在替换中包含一个文字换行符(前面有一个反斜杠).
BTW, your script seems to have some other issues. First, I don't know about the sed
on your system, but the versions I'm familiar with don't interpret \n
in the substitution as a newline (which I presume you want), but as a literal n
character. One solution is to include a literal newline in the substitution (preceded by a backslash).
此外,循环会针对每个找到的文件执行,但对于名称中没有句点的文件,第一个 sed
命令将删除它们,$v
是空的,您在 myscript.sh 中添加了一个空行.您应该将过滤 sed
调用放在 for
语句中,或者将其作为过滤器添加到 find
命令中.
Also, the loop executes for each found file, but for files that don't have a period in the name, the first sed
command removes them, $v
is empty, and you add a blank line to myscript.sh. You should either put the filtering sed
call in the for
statement, or add it as a filter to the find
command.
#!/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
这篇关于SED 坏替换错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!