Shell
根據文件類型和日期查找和移動目錄
我有一個目錄“新電影”,其中包含 200 多個子目錄“電影名稱(年份)”。子目錄“電影名稱(年份)”包含一個影片文件(avi/mkv)和幾個相關的 jpg/xml 文件。
我需要將包含至少 180 天前的影片文件的所有目錄移動到另一個目錄。
例如:
新電影/電影 A(年)將包含 movie.mkv、folder.jpg 和 movie.xml,我想將它們移動到其他地方的同名子目錄,所有文件都存在且完好無損。
在本網站的其他地方查看後,我嘗試過:
cd "/mnt/user/New Movies/" find -type f \( -name "*.avi" -or -name ".*mkv" \) -mtime +180 -exec sh -c 'mv "${0%/*}" /mnt/user/Movies' {} \;
該命令成功地將第一個子目錄和所有文件移動到它們的新首頁,但是在此之後的每個操作都會返回錯誤
find: './Movie B (year)': No such file or directory find: './Movie C (year)': No such file or directory
等等通過“新電影”下包含的所有目錄,無論它們是否應該被移動。
不要
-exec mv
目前正在檢查的目錄find
。當你這樣做時,似乎find
會感到困惑。解決方法:首先找到目錄,然後移動它們。
cd "/mnt/user/New Movies/" find -type f \( -name "*.avi" -or -name ".*mkv" \) -mtime +180 \ -printf "%h\0" | xargs -0 mv -t /mnt/user/Movies
解釋:
-printf
根據格式字元串列印匹配。%h
列印匹配的路徑部分。這對應"${0%/*}"
於您的命令中的 。\0
使用空字元分隔項目。如果文件名包含換行符,這只是預防措施。xargs
從管道收集輸入,然後在附加輸入的情況下執行其參數。-0
告訴 xargs 期望輸入以空值分隔而不是換行符分隔。mv -t <target>
允許mv
在最後附加所有源參數的情況下呼叫。請注意,這仍然不是絕對安全的。一些怪異的調度程序計時結合管道緩衝區可能仍會導致在移出目錄
mv
之前執行。find
為了防止這種情況,您可以這樣做:cd "/mnt/user/New Movies/" find -type f \( -name "*.avi" -or -name ".*mkv" \) -mtime +180 \ -printf "%h\0" > dirstomove xargs -0 mv -t /mnt/user/Movies < dirstomove
背景說明:
我假設您
find
的情況如下:
find
遍歷目錄/mnt/user/New Movies/
。在那裡,它會記下其記憶體中的可用目錄。find
使用系統呼叫遍歷其中一個子目錄chdir(subdirname)
。- 在裡面
find
找到一個通過過濾器的電影文件。find``mv
使用給定的參數執行。mv
將目錄移動到/mnt/user/Movies
.find
使用系統呼叫返回父目錄chdir(..)
,現在指向/mnt/user/Movies
而不是/mnt/user/New Movies/
find
很困惑,因為它沒有找到前面提到的目錄並引發了很多錯誤。這個假設是基於這個問題的答案:find -exec mv 在第一個 exec 之後停止。我不知道為什麼
find
在這種情況下停止工作並在您的情況下引發錯誤。不同版本的find
可能是解釋。