我有一臺帶有兩個目錄樹的計算機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