以往我在 Windows 下整理 NAS 上的文件时,遇到需要合并的同名文件夹时,只需要简单地把其中一个拖入到另一个文件夹所在的目录中。如若没有遇到同名文件冲突的情况,那么整个过程会在一瞬间完成,它时十分符合操作直觉的。
但在 macOS 下想要像这样合并两个文件夹却是意外地困难。
在 macOS 下,Finder 默认只为同名文件夹冲突提供了“停止”与“替换”两个选择,无须怀疑,这里的“替换”并没有字面之外意思。而在一番搜索后,不难会发现苹果设置了一个可以用 opt
键触发的隐藏的“合并”按钮。
但这个“合并”始终是以拷贝的形式进行的,这意味着每一次合并文件夹的时候 Finder 都会制造一次毫无意义的磁盘写入。而这份无意义的写入所造成的影响对于 NAS 用户来说,则会被传输协议、磁盘性能、网络带宽等因素进一步放大,最后从无意义进化成了一种折磨。
对此,如果不愿意选择那些更迎合 Windows 使用习惯的第三方文件管理器的话,使用跟 Finder 高度耦合的 Automator 来跑一个合并行为更接近 Windows 的脚本可以算是一个折中办法。
Automator 能够很方便得透过 Finder 获取所选文件的路径,同时它也能调用 Finder 的弹窗选择器来手动选择一个路径来作为变量使用。像是这样:
在运行工作流的时候,所有被选择的项目的路径都会依序作为列表值被输入,而在通过请求访达项目选择输出路径后,就得到了一个类似 ['-c', 'path1', 'path2', 'path3',...'pathN']
的列表。起始项始终是固定的值 '-c'
,所以此处只需要截取第二项至倒数第二项作为 src
,以及结尾项作为 dst
即可。
有了 src
和 dst
,事情就变得非常简单了,这里就用 Python 的 shutil
模块起一个脚本。
import sys,os,shutil
src = sys.argv[1:-1]
dst = sys.argv[-1]
for item in src:
for root,dirs,files in os.walk(item):
for file in files:
old = os.path.join(root,file)
start = os.path.dirname(item.rstrip('/'))
new = os.path.join(dst,os.path.relpath(old,start))
if not os.path.exists(os.path.dirname(new)):
os.makedirs(os.path.dirname(new))
shutil.move(old,new)
shutil.rmtree(item)
现在将脚本拖入工作流,传递输入选择“作为自变量”,再把脚本的输出作为文本导出一份,最后这个样子就大抵堪用了。
最后来验证一下,看起来没有问题