我有一个简单的 bash 脚本:
input_dir="`dirname $1`/`basename $1`/"
output_dir="`dirname $2`/`basename $2`/"
ext=$3
...
...
...
echo -n `rename "-f" "'s/.*([0-9]{11}_[0-9]{11}).*\.(.*$)/$1.$2/'" "$output_dir"*.$ext`
问题是它不起作用,因为匹配组$N
与脚本的命令行参数冲突。我该如何解决这个问题?
答案1
关于您提出的问题:在您不希望发生任何替换的文字字符串周围使用单引号。如果您需要在该字符串中使用单引号,请将其键入为'\''
。
echo -n `rename "-f" 's/.*([0-9]{11}_[0-9]{11}).*\.(.*$)/$1.$2/' "$output_dir"*.$ext`
您的代码还有其他问题。变量替换(如$1
和 )$2
或命令替换(如)的结果`rename …`
由 shell 解析,它对结果执行分词和通配符。始终在变量替换和命令替换周围使用双引号除非您知道需要忽略它们。此外,不要使用反引号,因为它们以棘手且依赖于 shell 的方式处理嵌套引号。博物馆之外的所有 shell 都支持更理智的$(…)
语法。此外,您还需要在and--
的调用上使用 a ,以防或以 a 开头,因此看起来像是一个选项。dirname
basename
$1
$2
-
input_dir="$(dirname -- "$1")/$(basename -- "$1")/"
output_dir="$(dirname -- "$2")/$(basename -- "$2"/)"
ext="$3" # here it would be ok to omit the quotes, but if you're unsure of the rules, put the quotes in
echo -n "$(rename -f 's/.*([0-9]{11}_[0-9]{11}).*\.(.*)$/$1.$2/' "$output_dir"*".$ext")"
顺便说一句,我不明白你想在这里实现什么目标。您调用它的方式rename
不会产生任何输出。
答案2
一般来说,您可以阻止 shell 解释元字符
通过使用反斜杠 ( \
) 对其进行转义。所以,你可以防止全部$
参数中的the
rename
通过在前面添加反斜杠来扩展:
echo -n `rename "-f" "'s/.*([0-9]{11}_[0-9]{11}).*\.(.*\$)/\$1.\$2/'" "$output_dir"*.$ext`
在这种特殊情况下,由于字符串s/.*([0-9]...$2/
不需要任何 shell 级替换(您问题的重点是如何防止它们),因此您可以将其括在单引号 ( '
) 中,这会阻止所有 shell 处理:
echo -n `rename "-f" 's/.*([0-9]{11}_[0-9]{11}).*\.(.*$)/$1.$2/' "$output_dir"*.$ext`
(请注意,您不需要将 引起来-f
,因为它不包含任何 shell 元字符。)