一次从多个文件中删除公共前缀

时间:2016-01-27 23:58:22

标签: bash unix find pipe cp

我必须对单个文件夹中的多个文件执行以下操作:

  

删除"陌生人的剑 - "部分来自"陌生人之剑 - Aganai No Yuki - ストレンヂア无皇刃谭 - [20-25] .mp3"。

为此,我构建了以下命令:

find . -name '*.mp3' -exec sh -c "cp {} `echo {} | cut -f2- -d'-' | cut -c2-`" \;

但是在执行上述命令时,我收到以下错误:

cp: target ‘}’ is not a directory

即使我将上述命令改为考虑文件名中的空格,它仍然会给我同样的错误。

find . -name '*.mp3' -exec sh -c "cp {} "`echo {} | cut -f2- -d'-' | cut -c2-`"" \;

请有人解释为什么我收到错误并建议另外一个班轮来执行上述操作(最好使用find和exec和cp)。

1 个答案:

答案 0 :(得分:1)

问题是双引号不会阻止命令替换;就是这样的事情:

echo "`echo foo`"

打印foo而不是`echo foo`

因此,在您的示例中,命令替换在 find被调用之前发生。就是这样:

find . -name '*.mp3' -exec sh -c "cp {} `echo {} | cut -f2- -d'-' | cut -c2-`" \;

相当于:

find . -name '*.mp3' -exec sh -c "cp {} }" \;

因为命令echo {} | cut -f2- -d'-' | cut -c2-打印}

要解决此问题,您可以改为使用单引号。

此外,您需要在命令的几个位置使用双引号,以防止您的文件名被解释为echocp的多个参数:< / p>

find . -name '*.mp3' -exec sh -c 'cp "{}" "`echo "{}" | cut -f2- -d- | cut -c2-`"' \;

(请注意,我已将-d'-'更改为-d-。无论如何,这些都是等效的,所以没有必要做任何花哨的事情来获得-d'-'在单引号字符串中。)