我们的办公室使用 Mac 上的 Dropbox 来组织我们的设计项目。几年来,许多文件和文件夹都使用 Windows 操作系统上非法的字符保存。我们需要将一些 Windows 操作系统计算机添加到我们的办公室。这造成了一个问题,因为这些文件都无法正确同步。
我对运行 OSX 脚本知之甚少,但偶然发现了这个指南,它几乎满足了我的需求,只是我需要它在所有子文件夹和文件中都能正常工作。这个人创建了一个包装在程序中的自动化脚本。
这样的脚本是否可以包含所有子文件夹和文件?此脚本删除了所有空格和特殊字符,但如果可能的话,用下划线替换它们会更好。
谢谢
答案1
轻松获得slhck 的脚本 如果您使用 bash,要以递归方式搜索子文件夹和文件,方法是添加
shopt -s globstar
然后更改*
为**
。如果您的目录名称中包含“非法”字符,则此方法将无法正常工作。您可以通过运行脚本来解决这个问题n+1 次,其中n是任何路径中含有非法字符的最大目录数。例如,如果您有一个f@cat
目录,dog#
该目录下还有一个目录,fox!
该目录下还有一个目录,则您需要运行该脚本四次。下面我给出了一种更好的方法。
- slhck 的脚本实际上应该使用
mv -i
而不是mv
。如果您有名为 和 的文件,cost+tax
则cost-tax
脚本会将它们重命名为costtax
(或cost_tax
,在我们进行该更改之后)。这会用第二个文件覆盖第一个文件。-i
(我交互式(nteractive)选项会导致mv
要求确认。您必须手动处理此类冲突。 - 要用下划线替换“非法”字符,请更改
${file//[^0-9A-Za-z.]}
为${file//[^0-9A-Za-z.]/_}
(或者更好的是${file//[^0-9A-Za-z._]/_}
)。
因此,通过上述更改,slhck 的脚本变成
shopt -s globstar
for f in "$1"/**
do
dir="$(dirname "$f")"
file="$(basename "$f")"
mv -i -- "$f" "${dir}/${file//[^0-9A-Za-z._]/_}"
done
运行此程序时,请务必提供一个参数(例如,.
);否则它将尝试重命名文件系统中的所有文件(从 开始/
)。您可能应该在脚本中放入一些内容来验证参数$1
不为空。
这对于名称中包含非法字符的目录存在问题,因为 会**
扩展为 下子树中所有文件和目录的列表,$1
其中 的分支按从上到下的顺序排列。因此,如果您有f@cat/dog#
,它将看到f@cat
和f@cat/dog#
作为参数。因此它将重命名f@cat
为f_cat
,然后查找f@cat/dog#
— 不再存在,因为它已重命名为f_cat/dog#
。我们可以通过执行以下操作来解决这个问题
find "$1" -depth -name '*[^0-9A-Za-z._]*' -exec sh -c \
'for f do dir="$(dirname "$f")"; file="$(basename "$f")";
mv -i -- "$f" "${dir}/${file//[^0-9A-Za-z.]/_}"; done' sh {} +
选项-depth
告诉find
它按从下到上的顺序查看目录分支。该-name
指令使它只查看以下文件名:需要重命名。(另一个脚本在尝试将文件重命名为自己时会给出错误消息,因为其名称不包含任何非法字符。)
find
然后将名称传递给 shell,该 shell 执行与脚本相同的操作,但是作为单个命令。