在 macOS 上使用 find 和 mv 重命名目录

在 macOS 上使用 find 和 mv 重命名目录

我正在努力使用重命名目录和文件的命令。

  • 操作系统:MACOS 11.4
  • 目标:通过用下划线替换空格来重命名目录和文件_
  • 命令尝试:
    find . -maxdepth 1 -iname "* *" -exec sh -c 'fichier="{}"; mv -- $fichier ${fichier// /_}' \;
    

我使用它是find因为我希望能够一次浏览目录树的深度 1 层。

该命令的结果是:

usage: mv [-f | -i | -n] [-v] source target
       mv [-f | -i | -n] [-v] source ... directory

所以mv我不是用来echo检查命令

find . -maxdepth 1 -iname "* *" -exec sh -c 'fichier="{}"; echo $fichier ${fichier// /_}' \;

这似乎按我的预期工作:

./Job offers etc ./Job_offers_etc
./School results ./School_results
./Famille et Souvenirs ./Famille_et_Souvenirs
./KID education ./KID_education
./Template Open Office-MS Office ./Template_Open_Office-MS_Office
./Mode Emplois ./Mode_Emplois
./cartres de voeux ./cartres_de_voeux

我使用时做错了什么mv

答案1

您遇到的情况是建议您这样做的原因之一(几乎)总是引用你的 shell 变量

在您的情况下,由于您为 shell 变量分配了fichier一个包含空格的文件名,因此当您“按原样”使用该变量时,shell 将执行分词,即就像$fichier.这意味着Job offers etc作为参数的目录mv将被解释为尝试将三个文件移动Joboffers目标etc目录Job_offers_etc(1)

为了避免该问题,请在变量引用周围放置双引号,如 中所示"$fichier"


(1)这实际上可能是危险的;在某些设置中,如果目标目录不存在,该命令可能会导致三个文件被重命名为相同的名称,从而有效地用第三个文件覆盖前两个文件。

答案2

如果您有 perl 重命名实用程序,文件::重命名,已经安装了,这很容易。如果您还没有,那么您应该安装它 - 它使困难的批量重命名操作变得非常简单。

如果你有自制已安装,您可以使用以下命令安装它brew install rename(请参阅在酿造上重命名),否则你可以安装它cpan.同样,如果您的 Mac 上没有安装 Homebrew,您应该,它使您可以访问数千个包。

然后,您可以将当前目录中所有文件名+目录名中的空格替换为下划线:

rename -n 's/ /_/g' *

-n选项使其成为一次试运行,它实际上不会重命名任何文件,它只会向您显示将重命名的内容。一旦您确定它执行了您想要的操作,请删除该-n选项或将其替换-v为详细输出。

几乎不需要或不需要排除不包含空格的文件,因为如果重命名脚本实际上更改了文件名,则 perl rename 只会尝试重命名文件,并且上面的脚本不会更改没有空格的文件名。

它还将拒绝在现有文件名上重命名文件,除非您强制使用-f.

如果需要,您可以将它与 find 一起使用,并且它可以理解 NUL 分隔的输入(因此它可以处理任何文件名,甚至those其中包含换行符)。例如

find . -maxdepth 1 -iname "* *" -print0 | rename -0 -n 's/ /_/g'

答案3

由于findand的组合sh -c以及引用变量的需要,使用循环可能更容易for

for file in *\ *
do
  newfile=$(echo "$file" | tr ' ' _)
  mv -i "$file" "$newfile"
done

相关内容