通过 exec 在 find 的输出上替换 Bash 变量

She*_*ish 5 bash exec find built-in substitution

有什么方法可以bashfind的输出应用变量替换吗?我知道我已经看到有人在堆栈溢出时这样做了,但我似乎再也找不到那个特定的帖子了。

例如,假设我想将文件重命名*.png*_copy.png. 我知道我可以使用rename它来做到这一点,但这只是一个思想实验。

现在我希望能够做这样的事情:

find . -name "*png" -exec mv "{}" "${{}%.*}_copy.png" \;
Run Code Online (Sandbox Code Playgroud)

这会导致无效替换。当然,我可以先将输出分配给一个变量,然后在子 shell 中应用替换,但这真的是唯一的方法吗?

find . -name "*.png" -exec bash -c 'var="{}";  mv "{}" "${var%.*}_copy.png"' \;
Run Code Online (Sandbox Code Playgroud)

或者有什么办法可以直接实现{}

共识

正如Etan Reisner所说,处理 find 输出的更好、更安全的方法是将其作为位置参数传递。

find . -name "*.png" -exec bash -c 'mv "$0" "${0%.*}_copy.png"' "{}" \;
Run Code Online (Sandbox Code Playgroud)

hek*_*mgl 3

我花了一段时间才得到这个问题。基本上你问的是:

echo "${test.png%.png}"
Run Code Online (Sandbox Code Playgroud)

可以用来获取这个词test

答案是不。以 开头的字符串操作运算符是参数替换运算符${的子集。它们仅适用于变量,不适用于字符串文字,这意味着您需要之前将字符串存储在变量中。像这样:

img="test.png"
echo "${img%.png}"
Run Code Online (Sandbox Code Playgroud)

对于来自 Google 的旅行者,我会使用它rename来完成此特定任务。(正如OP在他的问题中已经提到的那样)。该命令可能如下所示:

find -name '*png' -execdir rename 's/\.png/_copy.png/' {} +
Run Code Online (Sandbox Code Playgroud)

  • 顺便说一句,您绝对不应该将 `{}` 直接嵌入到使用 `sh -c` 或类似命令运行的 shell 脚本中。对于空间/等来说不安全。(并且没有引用并不能解决它只是将问题转移到引用转义)。您应该始终将其作为位置参数传递给脚本。 (4认同)