在Linux中以下划线递归替换冒号

时间:2013-07-11 10:25:19

标签: find rename sh

首先,这是我在这里发表的第一篇文章,我必须指出我是Linux新手。

我们最近为办公室买了一个QNAP NAS盒子,在这个盒子里我们有大量数据从旧的Mac XServe机器上复制过来。许多文件和文件夹最初在名称中都有正斜杠(HFS +首先应该不允许这样做),复制到NAS时都用冒号替换。

我现在想要将所有冒号重命名为下划线,并在此处的另一个帖子中找到以下命令:pitfalls in renaming files in bash

然而,这个盒子上的Linux的味道不理解重命名命令,所以我不得不使用mv。我尝试使用下面的代码,但这只适用于当前文件夹中的文件,有没有办法可以将其更改为包含所有子文件夹?

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

我发现我可以使用find命令查找相关文件和文件夹,如下所示

文件:

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

文件夹:

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

我已经能够使用

导出上面的结果列表
find . -type f -name "*:*" > files.txt

我尝试使用下面的命令但是我收到一条错误消息,发现它不理解exec开关,所以有没有办法把这一切都输入一个命令,或者我可以用某种方式使用我之前导出的文件?

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

谢谢! 文森特

1 个答案:

答案 0 :(得分:0)

所以你的for循环代码可以正常工作,但只能在当前的dir中运行。此外,您还可以使用find构建一个文件,其中包含以下所有文件:文件名。

所以,正如你已经完成所有这些,我只是循环遍历文件的每一行,并执行相同的mv命令。

这样的事情:

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

编辑:

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

EG

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

希望这会有所帮助。

威尔