
我有兩個目錄需要合併在一起。這兩個目錄下的檔案都是大檔案(>=500MB)。
我想要歸檔的內容: 對於來源目錄中的檔案:如果目標目錄中不存在,mv
則將其歸檔到目標目錄(這很快,因為我們基本上是建立一個新的硬連結並取消連結來源檔案) ;如果目標目錄中存在,則將來源檔案複製到那裡並刪除來源檔案。
Linux系統中合併目錄最常用的方法是使用rsync
with--remove-source-files
選項。但這很慢,因為即使目標檔案不存在,它也會執行複製操作。
還有更好的想法嗎?謝謝。
答案1
基本上,您所描述的是將文件移至覆蓋目的地(如果存在)。所以只要移動它們即可。
答案2
有一個mv
失敗的案例。以下是一些範例資料:
mkdir -p src/d dest/d
touch src/d/f1 dest/d/f2
看看如何mv
失敗:
$ mv src/* dest/
mv: cannot move 'src/d' to 'dest/d': Directory not empty
$ mv -f src/* dest/
mv: cannot move 'src/d' to 'dest/d': Directory not empty
$ mv -fv src/* dest/
mv: cannot move 'src/d' to 'dest/d': Directory not empty
$ mv -fvi src/* dest/
mv: overwrite 'dest/d'? y
mv: cannot move 'src/d' to 'dest/d': Directory not empty
$ mv -fvi -t dest/ src/*
mv: overwrite 'dest/d'? y
mv: cannot move 'src/d' to 'dest/d': Directory not empty
所以製作一個腳本檔:
vim supermove
此範例不進行錯誤檢查(免責聲明:對我有用,但請測試它是否對您有用...也許與echo
before一起使用mv
),並將覆蓋具有相同路徑的檔案。它使用 find ,\;
效率極低,但+
不能與"$dest"
prepending 一起正常工作。舊版本會建立一些沒有前綴路徑的目錄,而新版本的 find 會說:
find: In '-exec ... {} +' the '{}' must appear by itself, but you specified 'dest/{}'
不過,您也許可以找到一種使用 xargs 來解決該問題的方法。 (我移動 8TB 的 64k 檔案花了幾分鐘)。添加此內容:
#!/bin/bash
src=$1
dest=$2
src=$(readlink -f "$src")
dest=$(readlink -f "$dest")
cd "$src"
# also copy hidden files
shopt -s dotglob
# make dirs (missing old permission,acl,xattr data), and then mv the files
time find * -type d -exec mkdir -p "$dest"/{} \;
time find * -type f -exec mv {} "$dest"/{} \;
# also copy permissions, acls, xattrs
rsync -aAX "$src"/ "$dest"/
並使其可執行:
chmod +rx supermove
並運行它
./supermove src/ dest/
結果......之前:
$ find src dest
src/
src/d
src/d/f1
dest/
dest/d
dest/d/f2
後:
$ find src dest
src
src/d
dest
dest/d
dest/d/f1
dest/d/f2
現在src/
應該只是空目錄。如果是這樣,您可以rm -r src
進行清理。
答案3
mv
選項都是關於衝突解決的:
選一個:
-f force (always overwrite)
-i interactive (ask whether to overwrite)
-n no clobber (no overwrite)
這也很好:
-v verbose
否則,資料可能會遺失和/或不清楚到底發生了什麼。
mv 在相同的檔案系統上也更優越,因為它只是更新目錄 inode,檔案不應該混亂。另一件事是,操作越大,出現軟錯誤等問題的可能性就越大。