1

首先,这是我在这里的第一篇文章,我必须说明我是一个完全的 Linux 新手。

我们最近为办公室购买了一个 QNAP NAS 盒子,在这个盒子上我们有大量数据是从一台旧的 Mac XServe 机器上复制的。许多文件和文件夹的名称最初都带有正斜杠(HFS+ 一开始就不应该允许这样做),当复制到 NAS 时,它们都被替换为冒号。

我现在想将所有冒号重命名为下划线,并在这里的另一个线程中找到了以下命令:在 bash 中重命名文件的陷阱

但是,这个盒子上的 Linux 风格不理解 rename 命令,所以我不得不使用 mv 代替。我尝试使用下面的代码,但这仅适用于当前文件夹中的文件,有没有办法可以将其更改为包含所有子文件夹?

for f in *.*; do mv -- "$f" "${f//:/_}"; done

我发现我可以使用以下find命令找到所有有问题的文件和文件夹

文件:

find . -type f -name "*:*" 

文件夹:

find . -type d -name "*:*"

我已经能够通过使用导出上述结果列表

find . -type f -name "*:*" > files.txt

我尝试使用下面的命令,但我从 find 收到一条错误消息,说它不理解exec开关,所以有没有办法将这一切通过管道传输到一个命令中,或者我可以以某种方式使用我之前导出的文件?

find . -depth -name "*:*" -exec bash -c 'dir=${1%/*} base=${1##*/}; mv "$1" "$dir/${base//:/_}"' _ {} \;

谢谢!文森特

4

1 回答 1

1

因此,您的 for 循环代码有效,但仅在当前目录中有效。此外,您可以使用 find 来构建一个文件,其中包含文件名中带有 : 的所有文件。

因此,正如您已经完成了所有这些,我将遍历文件的每一行,并执行相同的 mv 命令。

像这样的东西:

for f in `cat files.txt`; do mv $f "${f//:/_}"; done

编辑:

正如triplee 所指出的,使用while 循环是一个更好的解决方案

例如

while read -r f; do mv "$f" "${f//:/_}"; done <files.txt

希望这可以帮助。

将要

于 2013-07-11T11:13:56.623 回答