Bash 通过 exec 对 find 的输出进行变量替换
Bash variable substitution on find's output through exec
有什么方法可以对 find
的输出应用 bash
变量替换吗?我知道我已经看到有人在堆栈溢出时这样做了,但我似乎再也找不到那个特定的 post。
举个例子,假设我想将文件 *.png
重命名为 *_copy.png
。我知道我可以使用 rename
来做到这一点,但这只是一个思想实验。
现在我希望能够做这样的事情:
find . -name "*png" -exec mv "{}" "${{}%.*}_copy.png" \;
这导致无效替换。当然,我可以先将输出分配给一个变量,然后在子shell中应用替换,但是这真的是唯一的方法吗?
find . -name "*.png" -exec bash -c 'var="{}"; mv "{}" "${var%.*}_copy.png"' \;
或者有什么方法可以直接从{}
实现吗?
共识
正如 Etan Reisner 所说,处理 find 输出的更好更安全的方法是将其作为位置参数传递。
find . -name "*.png" -exec bash -c 'mv "[=13=]" "${0%.*}_copy.png"' "{}" \;
我花了一段时间才明白这个问题。基本上你问的是:
echo "${test.png%.png}"
可用于获取单词test
。
答案是否定的。 string manipulation operators starting with ${
are a subset of the parameter substitution operators。它们仅适用于变量,不适用于字符串文字,这意味着您需要先将字符串存储在变量中。像这样:
img="test.png"
echo "${img%.png}"
仅针对来自 Google 的旅行者,我会使用 rename
来完成这项特定任务。 (正如 OP 在他的问题中已经提到的那样)。该命令可能如下所示:
find -name '*png' -execdir rename 's/\.png/_copy.png/' {} +
有什么方法可以对 find
的输出应用 bash
变量替换吗?我知道我已经看到有人在堆栈溢出时这样做了,但我似乎再也找不到那个特定的 post。
举个例子,假设我想将文件 *.png
重命名为 *_copy.png
。我知道我可以使用 rename
来做到这一点,但这只是一个思想实验。
现在我希望能够做这样的事情:
find . -name "*png" -exec mv "{}" "${{}%.*}_copy.png" \;
这导致无效替换。当然,我可以先将输出分配给一个变量,然后在子shell中应用替换,但是这真的是唯一的方法吗?
find . -name "*.png" -exec bash -c 'var="{}"; mv "{}" "${var%.*}_copy.png"' \;
或者有什么方法可以直接从{}
实现吗?
共识
正如 Etan Reisner 所说,处理 find 输出的更好更安全的方法是将其作为位置参数传递。
find . -name "*.png" -exec bash -c 'mv "[=13=]" "${0%.*}_copy.png"' "{}" \;
我花了一段时间才明白这个问题。基本上你问的是:
echo "${test.png%.png}"
可用于获取单词test
。
答案是否定的。 string manipulation operators starting with ${
are a subset of the parameter substitution operators。它们仅适用于变量,不适用于字符串文字,这意味着您需要先将字符串存储在变量中。像这样:
img="test.png"
echo "${img%.png}"
仅针对来自 Google 的旅行者,我会使用 rename
来完成这项特定任务。 (正如 OP 在他的问题中已经提到的那样)。该命令可能如下所示:
find -name '*png' -execdir rename 's/\.png/_copy.png/' {} +