我有一台带有两个目录树的计算机A.第一个目录包含跨越几年的原始模型日期。第二个目录是第一个目录的副本和几个附加文件。还有第二台计算机包含一个与计算机A上的第二个目录相同的目录树(新的mod时间和附加文件)。如何更新两台机器上两个较新目录中的文件,以便文件的修改时间与原始文件相同?请注意,这些目录树大小为10 GB,所以解决方案必须包含一些仅向第二台计算机发送日期信息的方法。跨多个目录的同步文件修改时间
回答
我认为rsync的(与正确的选项) 将做到这一点 - 它声称只发送 文件差异,所以想必 工作了,有没有差异 转移。
- 次保留修改时间,这是你想要的。
见(例如) http://linux.die.net/man/1/rsync
同时添加-I,--ignore次不跳过匹配的大小和时间
使所有文件“转移”和信任的文件rsync的的文件不同的优化,以使其“相当有效。” - 节选看到从下面的man page
-t,--times 这告诉rsync的传输与文件一起修改时间和更新它们的遥控器上SYST EM。请注意,如果未使用此选项,排除未被修改的文件的优化将无法生效;换句话说,缺少-t或-a将导致下一次传输的行为就像使用-I一样,导致所有文件都被更新(尽管如果文件没有真正改变,rsync算法会使更新效率更高,你使用-t)会好得多。
我会浏览源目录树中的所有文件,并将修改时间从它们收集到可以在其他目录树上运行的脚本中。你需要小心几个'陷阱'。首先,确保您的输出脚本具有相对路径,并确保您从适当的目标目录(它应该是目标树的根目录)运行它。另外,在更换机器时,请确保您使用的是与生成脚本的计算机上相同的时区。
下面是我放在一起的Perl脚本,它将输出需要更新其他目录树上的时间的touch
命令。根据目标机器的不同,您可能需要调整日期格式或命令选项,但这应该给您一个启动的地方。
#!/usr/bin/perl
my $STARTDIR="$HOME/test";
chdir $STARTDIR;
my @files = `find . -type f`;
chomp @files;
foreach my $file (@files) {
my $mtime = localtime((stat($file))[9]);
print qq(touch -m -d "$mtime" "$file"\n);
}
另一种方法,你可以尝试是使用NFS来连接远程目录,然后使用find
和touch -r
复制倍。
以下命令将确保TEST2获得分配了TEST1具有
touch -t `stat -t '%Y%m%d%H%M.%S' -f '%Sa' TEST1` TEST2
现在不是这里使用硬编码值相同的日期,你可以使用“查找”工具,然后运行查找文件通过远程计算机上的SSH进行触摸。但是,这意味着您可能必须输入每个文件的密码,除非您将SSH切换为证书验证。我宁愿不要在一个超级花式的单线上做这一切。相反,让我们使用临时文件。首先进入有问题的目录并运行一个查找(你可以根据文件类型,大小,扩展名进行过滤,无论你喜欢什么,请参阅“man find”以获取详细信息。我只是通过类型文件进行过滤以排除任何目录):
find . -type f -print -exec stat -t '%Y%m%d%H%M.%S' -f '%Sm' "{}" \; > /tmp/original_dates.txt
现在我们有一个看起来像这样的文件(在我的例子中,只有两个项目有):
# cat /tmp/original_dates.txt
./test1
200809241840.55
./test2
200809241849.56
现在只要将文件在拷贝到其他机器,并将其放置在目录(以便相对文件路径匹配)并应用日期:
cat original_dates.txt | (while read FILE && read DATE; do touch -t $DATE "$FILE"; done)
也可以使用包含空格的文件名。
其中一个注意事项:我使用stat中的最后一个“修改”日期,因为这是您在问题中写的内容。然而,听起来好像你想使用“创建”日期(每个文件都有一个创建日期,最后修改日期和最后访问日期),你需要稍微改变统计调用。
'%Sm' - last modification date
'%Sc' - creation date
'%Sa' - last access date
然而,触摸只能更改修改时间和访问时间,我觉得它不能改变文件的创建时间......因此,如果这是你的真实意图,我的解决方案可能是分最佳...但在这种情况下,您的问题也是如此;-)
我最后不得不使用touch new_file -t \`date -d @ \``stat -t -c“%Y”old_file \\`+%Y%m%d%H%M%S \` – kormoc 2012-06-06 21:23:02
Paul的答案部分正确,rsync
是能够做到这一点,但具有不同的参数。正确的命令是
rsync -Prt --size-only original_dir copy_dir
其中-P
使局部传输和显示进度指示,-r
递归通过子目录,-t
保留时间标记和--size-only
不转移匹配大小的文件。
我改用下面的Python脚本。
Python脚本的运行速度比为每个文件创建新进程的方法快得多(如使用find
和stat
)。下面的解决方案也适用于系统之间的时区差异,因为它使用UTC时间。它也适用于包含空格的路径(但不包含包含换行符的路径!)。它不会为符号链接设置时间,因为the operating system provides no mechanism to modify the timestamp of a symlink,但是在文件管理器中,符号链接指向的文件时间反而显示。它使用maxTime
参数来避免重置从原始目录复制后实际修改的文件的日期。
listMTimes.py:
import os
from datetime import datetime
from pytz import utc
for dirpath, dirnames, filenames in os.walk('./'):
for name in filenames+dirnames:
path = os.path.join(dirpath, name)
# Avoid symlinks because os.path.getmtime and os.utime get and
# set the time of the pointed file, and in the new directory,
# the link may have been redirected.
if not os.path.islink(path):
mtime = datetime.fromtimestamp(os.path.getmtime(path), utc)
print(mtime.isoformat()+" "+path)
setMTimes。PY:
import datetime, fileinput, os, sys, time
import dateutil.parser
from pytz import utc
# Based on
# http://stackoverflow.com/questions/6999726/python-getting-millis-since-epoch-from-datetime
def unix_time(dt):
epoch = datetime.datetime.fromtimestamp(0, utc)
delta = dt - epoch
return delta.total_seconds()
if len(sys.argv) != 2:
print('Syntax: '+sys.argv[0]+' <maxTime>')
print(' where <maxTime> an ISO time, e. g. "2013-12-02T23:00+02:00".')
exit(1)
# A file with modification time newer than maxTime is not reset to
# its original modification time.
maxTime = unix_time(dateutil.parser.parse(sys.argv[1]))
for line in fileinput.input([]):
(datetimeString, path) = line.rstrip('\r\n').split(' ', 1)
mtime = dateutil.parser.parse(datetimeString)
if os.path.exists(path) and not os.path.islink(path):
if os.path.getmtime(path) <= maxTime:
os.utime(path, (time.time(), unix_time(mtime)))
用法:在第一目录(原)运行
python listMTimes.py >/tmp/original_dates.txt
然后在第二目录(原始的一个副本,可能会进行一些修改过的文件/加入/删除)运行这样的事情:
python setMTimes.py 2013-12-02T23:00+02:00 </tmp/original_dates.txt
- 1. 跨网络的文件/目录同步
- 2. 跨多个设备同步时间戳
- 3. JQuery插件修改时间跨度
- 4. Hadoop目录/文件的最后修改时间
- 5. 修改多个项目的webconfig文件
- 6. 如何在不修改目录的修改时间戳的情况下将文件添加到目录?
- 7. 跨多台服务器同步文件
- 8. 使用ANT将目录中所有文件的“修改”时间更改为其他目录中文件的“修改”时间
- 9. Git回购与多个目录中的文件(dotfiles同步)
- 10. php获取空目录修改时间?
- 11. 根据修改时间删除目录
- 12. 在目录上同步时间戳
- 13. 按修改时间排序文件(包括所有子目录中的文件)
- 14. 从一个目录中获取特定数量的文件,修改时间
- 15. 使用rsync从多个目录同步txt文件
- 16. 修改文件的名称在目录
- 17. 如何使用批处理文件修改所有文件和子目录的时间戳(最后修改)
- 18. 使用lsyncd同步多个目录
- 19. 将更改应用于同一目录中的多个文件
- 20. 在iphone中获取文档目录文件的日期修改时间
- 21. 当许多文件在同一时间,当许多文件添加到在同一时间目录
- 22. 多个.dockerignore文件在同一目录
- 23. 当Typescript定义跨多个文件拆分时,使用插件修改模块
- 24. 跨多个实体的同步ID
- 25. 如何观看目录文件修改
- 26. 从黑客(读目录,修改文件)
- 27. 用Ant修改文件获取目录
- 28. hdfs何时更改目录的访问时间和修改时间?
- 29. 如何同步目录b中的目录a中的文件?
- 30. 为文件/目录提供与另一个文件/目录相同的修改日期
其实rsync使用日期/时间来决定是否有差异(它只会同步文件具有较新的mod本地的日期比远程);你不能使用rsync来做这件事。此外rsync不会同步任何东西,除非它决定同步文件内容,并且这被排除在提问者之外。 – Mecki 2008-09-24 17:08:14