如何递归地更改文件的日期戳,但仅当现有文件与特定日期不匹配时?

如何递归地更改文件的日期戳,但仅当现有文件与特定日期不匹配时?

我有一个文件夹(许多文件和子文件夹,几百GB)。我使用 rsync 复制了该文件夹,但忘记保留时间戳。

新文件夹现已添加了许多新文件,并修改了现有文件。

我需要将旧文件夹的时间戳复制到新文件夹,但前提是文件在 2021 年 7 月 9 日之后尚未修改。

我不认为 rsync 会做到这一点。我想我必须使用touch -t,但需要一种有效的方法来处理所有文件。有没有更好的办法?或者,如果文件自 7 月 9 日以来没有被修改过,我该如何处理所有文件并更新时间戳。

谢谢。

答案1

这是一条应该有效的单行代码:

find /path/to/newdir -type f -not -newermt 09jul2021 -printf './%P\000' | rsync -r --files-from=- -0 --size-only --times /path/to/olddir/ /path/to/newdir/

该命令的前半部分生成一个以 null 分隔的文件列表,其中"newdir"自 2021 年 7 月 9 日以来未进行过修改,格式为相对于同步目录的路径。

该命令的后半部分rsync在该文件列表上运行,并更改它们的修改时间戳以"newdir"匹配"olddir"

答案2

最可靠的方法是使用 rsync 本身。

通过使用 --size-only 标志复制回旧文件夹,只会复制比旧文件夹更新的文件,因此不会影响现有文件的时间戳。

这对每个人来说都不是一个完美的答案,但这里的小改动因 --size-only 标志而丢失的风险对我来说不会成为问题。

我首先使用 --dry-run 运行它,然后使用 diff 检查结果以确保一切按预期工作。

答案3

与 GNU find/ touch.

cd newdir && find . -depth ! -newermt 2021-07-10 -exec \
  touch -hr '../olddir/{}' '{}' \;

(请注意,这里的 2021-07-10 表示 2021-07-10 早上 00:00:00,! -newertmt 2021-07-10T23:59:59.99999999如果要排除最后在午夜纳秒修改的文件,请更改为 )。

请注意,它touch为每个文件运行一个,因此效率不高。

如果您进行了busybox配置,以便sh小程序可以调用其他小程序而无需 fork+exec,则可以通过以下方式加快速度:

cd newdir && find . -depth ! -newermt 2021-07-10 -exec \
  busybox sh -c '
    for file do
      touch -hr "../olddir/$file" "$file"
    done' sh {} +

但请注意,您需要 busybox 1.34.0 或更高版本的touch小程序才能复制时间戳的纳秒部分。

相关内容