Mac OS X 工具是否只同步/复制时间戳而不是文件数据?没有文件数据传输,只有文件系统元数据被同步

Mac OS X 工具是否只同步/复制时间戳而不是文件数据?没有文件数据传输,只有文件系统元数据被同步

这是我目前的情况(简化了,实际上当然有很多和很大的文件):

Dir1/
  a b c
Dir2/
  a b c d

这种情况以前也发生过:

  • abc 从 Dir1 复制到 Dir2。
  • 在 Dir2 中,abc 的时间戳被意外修改。
  • d 被故意添加到 Dir2 中。

现在我想这样做:将 Dir2 同步回 Dir1。(致相关人员:我使用 rsync)

  • d 是新的,因此应该被复制。
  • Dir2 和 Dir1 中的 abc 的大小和数据内容相同,但它们的文件戳不同。因此它们将是不必要地复制。

我知道 rsync 可以通过 --checksum 或 --size-only 比较文件。但是这种磁盘/CPU 密集型检查必须在以后的每次同步中重复进行。相反,我更希望通过使用工具将原始文件时间戳从 Dir1 中的时间戳恢复到 Dir2 中的时间戳,一劳永逸地纠正我的错误。然后我的错误就被纠正了,将来的同步就可以高效运行了。

在 Windows 上,这些工具只能复制时间戳(不复制数据):

有人知道适合 Mac OS X 的 CLI / GUI 工具吗?

答案1

与标准 rsync 检查相比,rsync 中的 --size-only 标志既不占用大量 CPU 也不占用大量磁盘空间,事实上,它的速度更快,因为 rsync 通常将同时检查文件大小和时间戳。您可以使用 touch 命令明确匹配 Dir2 中 abc 的时间戳。您可以删除 dir2 中的文件,然后再次 rsync。如果文件很多,这些建议非常有用,因此您可以将它们包装在脚本或 find 中。请注意,如果您再次运行 rsync,在典型模式下但也使用 --partial 选项(例如 rsync -az --partial Dir1 Dir2),它不会再次复制文件,而是会尝试智能地同步它们,我相信在这种情况下最终只会传输时间戳。

答案2

时间戳对你来说可能不重要吗?从问题中无法判断你是更想保留它们还是更想在不复制所有数据的情况下进行 rsync。如果你不关心时间戳,你可以使用 touch 命令在两台机器上的所有文件上设置一个特定的日期,使它们相同。例如:

find dirX -type f -print | xargs touch -t 201108250000

然后运行 ​​rsync 应该可以正常工作,因为两个机器上的时间戳相同。我不在我的 OS X 机器附近,无法测试这是否有效,但我以前在 Linux 上做过这个。

答案3

我不确定使用 rsync 来实现这一点的好方法,也没有使用 max osx 的经验,不过下面是在 linux 上的尝试,我希望它对你有用或者“足够接近”。

警告:这肯定是至少优雅的方式来实现这一点:)

我们需要遍历 dir1 中每个在 dir2 中的文件,然后对其执行我们的黑魔法

#!/bin/bash
# warning, really inelegant bash follows
FROMDIR='dir1'
TODIR='dir2'

for FROMFILE in `find $FROMDIR -type f`; do
        TOFILE=`echo "$FROMFILE" | sed "s/^$FROMDIR/$TODIR/"`
        echo "trying $FROMFILE to $TOFILE"

        if [ -e "$TOFILE" ]; then
                NEWDATE=$(stat -c %y $FROMFILE | awk '{print $2, $1}')
                echo "would perform 'touch -d '$NEWDATE' $TOFILE'"
                #touch -d "$NEWDATE" $TOFILE # uncomment me if you want to perform changes
        fi  
done

第一次运行它时,它不会做任何修改,而只是回显它将要做的事情,如果你觉得这是你想要的,那么取消注释该行#touch -d "$NEWDATE" $TOFILE


解释

stat -c %y filename

以人类可读的格式提供文件的修改时间

touch -d "timestamp" filename

会将文件名的修改日期设置为时间戳,但是 touch 似乎对其所采用的时间格式很挑剔(它与 stat %y 的输出不太匹配,并且似乎也不允许纪元)。

awk '{print $2,$1}'

将重新排列输出,stat -c %y以便能够被touch -d

把这些放在一起我们得到

NEWDATE=$(stat -c %y fromfile | awk '{print $2, $1}')
touch -d "$NEWDATE" tofile

相关内容