SED 坏替换错误 [英] SED bad substitution error

查看:45
本文介绍了SED 坏替换错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆