我有一個名為 test 的資料夾,其中只有 jpeg 檔案。數千個文件。我需要將這數千個檔案(名稱為 1.jpg、2.jpg...345623.jpg)放入名稱為 001000、002000 的子資料夾中,每個子資料夾包含 1000 個檔案。因此,我需要以最高效的方式將所有 jpg 檔案從 test 資料夾移動到包含 1000 個 jpg 檔案的子資料夾中。
到目前為止我所擁有的是:
i=1;while read l;do mkdir $i;mv $l $((i++));done< <(ls|xargs -n1000)
答案1
find . -type f \
| split -l 1000 -a 3 --numeric-suffixes=1 \
--filter='target="${FILE}000"; mkdir "$target" && xargs -d "\n" mv -t "$target"' \
- ''
解釋:
find . -type f
尋找文件(也在子目錄中,但我相信在您的情況下還沒有子目錄)。split -l 1000 -a 3 --numeric-suffixes=1 ... - ''
從其 stdin (-
) 讀取資料並將資料分成區塊,每個區塊 1000 行長 (-l 1000
)。對於每個區塊,都有一個關聯的“名稱”,由空前綴 (''
) 和從 1 ( ) 開始、--numeric-suffixes=1
長度為 3 (-a 3
) 的數字後綴組成。此時,名稱實際上是001
,002
等等。--filter=...
為每個區塊單獨運行指定的命令,相應的名稱可用作$FILE
.運行的命令是target="${FILE}000"; mkdir "$target" && xargs -d "\n" mv -t "$target"
target="${FILE}000"
將名稱(如001
或 )轉換002
為您想要的未來目錄名稱(001000
或002000
等)並將其儲存在target
變數中。mkdir "$target"
使用所需名稱建立一個新目錄。xargs -d "\n" ...
讀取整個區塊(1000 個檔案路徑,或最後一個區塊中的更少)並使用每一整行(換行符號作為分隔符號-d "\n"
:)作為後面命令的參數。mv -t "$target"
將物件(由 傳遞xargs
)移至新建立的目錄。
筆記:
- 該命令不關心檔案名稱。
345623.jpg
不一定會最終出現在346000/
.可能的原因:find
不排序;但即使你放在和sort -n
之間,它也可能是......find
split
- 編號上有間隙。
split
無論如何,都會佔用 1000 個條目(除非它是最後一個區塊;如果是這樣,則 1000 個或更少)。
mkdir ... && xargs ...
xargs
如果失敗則不會運作mkdir
(注意現有目錄)。- 使用
cp -l -t "$target"
而不是mv -t "$target"
在目錄中建立硬鏈接,使當前目錄中現有的條目保持不變。這樣,萬一出現問題,只需rm -r
刪除目錄並重新開始即可。使用 時mv
,如果任務中斷,您最終會移動一些文件,有些則不會;這可能會一團糟。 - 我認為
-a 3
不會讓你過去999
(999000
在附加尾隨零之後)。如果split
需要創建更多區塊,它將在工作中失敗。因此,999
在運行命令之前請確保足夠。 - 帶有換行符的名稱會破壞程式碼(通常,您的檔案名稱看起來不錯)。