![我如何(在 Mac/Unix/Linux/脚本上)递归地将一个目录复制到另一个目录并仅替换未改变的文件?](https://linux22.com/image/1273496/%E6%88%91%E5%A6%82%E4%BD%95%EF%BC%88%E5%9C%A8%20Mac%2FUnix%2FLinux%2F%E8%84%9A%E6%9C%AC%E4%B8%8A%EF%BC%89%E9%80%92%E5%BD%92%E5%9C%B0%E5%B0%86%E4%B8%80%E4%B8%AA%E7%9B%AE%E5%BD%95%E5%A4%8D%E5%88%B6%E5%88%B0%E5%8F%A6%E4%B8%80%E4%B8%AA%E7%9B%AE%E5%BD%95%E5%B9%B6%E4%BB%85%E6%9B%BF%E6%8D%A2%E6%9C%AA%E6%94%B9%E5%8F%98%E7%9A%84%E6%96%87%E4%BB%B6%EF%BC%9F.png)
背景和问题
我最近转到了 Mac OS X,遇到了 Mac 的“功能”,即从外部驱动器复制文件会将文件修改/更新日期/时间戳重置为当前日期(Windows 不会这样做),这导致我 10 多年来备份的工作文件出现灾难,因为日期很重要。
因此,在我学会如何避免这种情况之前(例如在“cp”复制命令中使用-p“preserve”标志),我已经在新的Mac硬盘上添加了更多文件,并更新了现有的旧文件。
当前状态
- 我有一个备份外部硬盘,里面有我所有的旧数据和正确的修改日期
- 我有一个 Mac 硬盘,其中修改文件日期已重置(一两天)
- Mac 硬盘包含所有“真实”和“当前”文件内容,以及修改和添加的文件
我需要的
我需要
- 从外部硬盘复制所有原始文件,保留文件元数据(实际上只有修改日期),但仅在以下情况下覆盖新的内部 Mac 硬盘:
- 文件内容(md5 或其他)相同或
- 该文件是在最初灾难性应对发生的那天(当然,我可以在所有文件上看到)之后更新的(暗示该文件是新的或经过修改的)
- 确保副本将所有新文件和修改过的文件完整地保留在 Mac 内置硬盘上。
- “不需要提示/停止任何类型的复制(即不详细),但是可以”
- “递归复制 - 显然我想复制在导出中找到的所有*文件文件夹和子文件夹”
有什么办法吗?
我已经阅读了 Stack Overflow 上所有我能读到的资料,并检查了手册页和“rsync”和“cp”的信息,但就是找不到方法……
有人有好的工具、脚本、技巧或想法吗?
答案1
最后写了一个 Java 程序来做这件事... 不会在这里发布代码,因为它又快又脏又乱 ;) ... 但是它很强大,你可以从这里下载简单的源代码www.nexle.dk/permanent-downloads/StackExchange/FileModChanger.java.zip可以自由使用、修改、编译和使用(但不提供任何保证,运行前请检查和测试)。
该工具的基本功能是获取一个文件夹结构中文件的最后修改日期,并将其应用于另一个文件夹中的文件;
- 文件名和路径相同(安全)
- 文件内容相同(再次进行 md5 校验,以确保安全)
- 两个文件的日期并不相同
我对大约 500,000 个文件进行了测试,似乎运行良好
一些注释;
- 它只会更改上次修改的日期/时间/时间戳,因此应该是安全的
- 该工具默认处于“试运行”模式,这意味着它将向您展示它将做什么,但不会执行更改(“真实”模式由命令行参数“real”激活)
- 它使用了来自网络的一些代码(来源文件内)。
- 它可以更快,但它已经足够快了
- 第一次解析所有目录中的文件时,它有一个可爱的小进度指示器;)
如果您想仔细研究整个代码,您可能也能从一些代码中获得灵感;
如何在 Java 中更改文件修改日期;
File sourceFile = new File("/tmp/sourcefile");
File targetFile = new File("/tmp/targetfile");
long sourceDateModified = sourceFile.lastModified();
targetFile.setLastModified(sourceDateModified);
希望其他人也能发现它很有用。不过还是感谢大家的评论和提示。
您可以下载已完成工具的使用方法和控制台输出(参见上文);
$ java -classpath . FileModChanger
USAGE (dry run, NO file changes made):
FileModChanger <source folder with original dates> <target folder with new/erased dates>
USAGE (real run,file date changes WILL be made):
FileModChanger <source folder with original dates> <target folder with new/erased dates> real
$ java -classpath . FileModChanger /Volumes/Untitled/D/knowledge/ISYS\ Desktop\ 6/ /Knowledge/ISYS\ Desktop\ 6/
Starting DRY run....
Starting DRY run....
Starting DRY run....
Starting to retrieve list of files (this may take a LONG time)...
0 folders processed
DONE creating the list of files, starting comparison...
About to operate on Volumes/Untitled/D/knowledge/IS[...]S Desktop 6/ISYSDesktop6Setup.exe:
SRC:Tue Jul 01 11:29:46 EST 2003 - bff684bfac4ed37e4a6b9a05ab625855 - Volumes/Untitled/D/knowledge/IS[...]S Desktop 6/ISYSDesktop6Setup.exe
TRG:Tue Dec 21 04:05:24 EST 2010 - bff684bfac4ed37e4a6b9a05ab625855 - /Knowledge/ISYS Desktop 6/ISYSDesktop6Setup.exe
DONE processing all files..
$ java -classpath . FileModChanger /Volumes/Untitled/D/knowledge/ISYS\ Desktop\ 6/ /Knowledge/ISYS\ Desktop\ 6/ real
Starting REAL run....
Starting REAL run....
Starting REAL run....
Starting to retrieve list of files (this may take a LONG time)...
0 folders processed
DONE creating the list of files, starting comparison...
About to operate on Volumes/Untitled/D/knowledge/IS[...]S Desktop 6/ISYSDesktop6Setup.exe:
SRC:Tue Jul 01 11:29:46 EST 2003 - bff684bfac4ed37e4a6b9a05ab625855 - Volumes/Untitled/D/knowledge/IS[...]S Desktop 6/ISYSDesktop6Setup.exe
TRG:Tue Dec 21 04:05:24 EST 2010 - bff684bfac4ed37e4a6b9a05ab625855 - /Knowledge/ISYS Desktop 6/ISYSDesktop6Setup.exe
RESULT:
- BEFORE: Tue Dec 21 04:05:24 EST 2010
- AFTER: Tue Jul 01 11:29:46 EST 2003
DONE processing all files..
此外,如果您有大量文件和文件夹,则可能需要增加 Java 的内存。