重命名(1)当前目录之外的一组文件

重命名(1)当前目录之外的一组文件

Ubuntu 12.04 中的命令rename(手册页说它是 perl v5.14.2 2012-03-23 的一部分)在单个目录中运行良好,但我想在子目录中使用它(或者,更一般地说,在作为另一个命令的输出的文件列表上,通过反引号)。例如,我希望

rename "s/ /-/g"  `find .`

将当前目录下所有文件名中的所有空格更改为破折号。但此命令不执行任何操作。

编辑:更改rename -nrename。该选项适合安全实验,但在这里只会分散注意力。)

反引号没有问题,因为find .用 eg替换echo */*就可以了。

首先执行find . > foo,然后find .用替换cat foo,什么也不做。

即使将文件列表折叠成一行,用 替换find .find . | tr -d '\n'也无济于事。

哪个元素有问题?

答案1

这不会起作用:

rename 's/ /-/g'  `find .`

运行 find 命令后,shell 会对结果进行分词。因此,没有带空格的文件名能够完整保留下来:它被分成了几个部分。

您可以使用以下方法避免这种情况:

rename 's/ /-/g'  */*

在这种命令形式下,shell 不会进行分词,您的命令rename将会成功。这种形式甚至适用于包含空格、制表符或任何其他困难字符的文件名。

或者,使用 find -exec

find . -name '* *' -exec rename 's/ /-/g' {} +

此形式适用于包含空格、制表符或任何其他困难字符的文件名。

示范

为了查看哪里出了问题,让我们创建一个包含空格的文件

$ touch "a b c"
$ find .
.
./a b c

为了弄清楚发生了什么,让我们创建一个函数,将它看到的每个参数放在双引号内并显示它:

$ display() { printf '"%s"\n' "$@"; }

现在,我们可以用来display查看运行时发生的情况find .

$ display `find .`
"."
"./a"
"b"
"c"

这显示了单词拆分的实际效果。文件名a b c被拆分为三个独立的单词。

相关内容