我想知道每個+100Mb並且在上個月沒有被訪問過的文件,並且我已經成功寫入:
find / -size +100M -atime +30
現在我想將這些檔案移到名為 /big-not-used 的資料夾,並將其名稱更改為:file_nameYYYYMMDD
其中 file_name 是原始檔案的名稱,YYYYMMDD 是今天的日期,以年月日為單位。例如film.mkv
轉到/big-not-used/film.mkv20161031
我的句子是:
find / -size +100M -atime +30 -exec mv {} /big-not-used/... \;
但我不知道如何在文件名中附加今天的日期。我發現date +%Y-%m-%d
輸出:2016-10-31
這很有用。現在的疑問是如何取得這個檔案的名稱?下列的:
https://stackoverflow.com/questions/5456120/how-to-only-get-file-name-with-linux-find
... -exec basename {} \;
或許?
find / -size +100M -atime +30 -exec mv {} /big-not-used/$(basename {})$(date +%Y-%m-%d) \;
但它給出了一個錯誤,因為 basename 正在回覆檔案的完整路徑而不是我將使用的名稱:
${var##/*/}
取得檔案名,但問題是如何將basename {}
回應插入到前面表達式中的 var 中!
或許?
$(${$(basename {})##/*/})
但它說在意外的“}”附近有語法錯誤...
答案1
您正在接近:
find / -size +100M -atime +30 \
-exec mv {} /big-not-used/$(basename {})$(date +%Y-%m-%d) \;
$(...)
但如果不加引號,就會發生結構的外殼擴展find
在命令執行之前。換句話說,給定上面的命令行,實際執行的是:
find / -size +100M -atime +30 \
-exec mv {} /big-not-used/{}2016-10-30 \;
因為 的結果$(basename {})
只是{}
,這就是為什麼你最終得到完整路徑名。試試這個:
find / -size +100M -atime +30 \
-exec sh -c 'mv {} /tmp/big-not-used/$(basename {})$(date +%Y-%m-%d)' \;
為了進行測試,您可以替換mv
為echo mv
,如下所示:
find / -size +100M -atime +30 \
-exec sh -c 'echo mv {} /tmp/big-not-used/$(basename {})$(date +%Y-%m-%d)' \;
....並查看生成的命令是什麼樣的。
答案2
我改進了lark的解決方案,只進行一次sh
呼叫:
find / -size +100M -atime +30 -exec sh -c \
'for f do mv "$f" /tmp/big-not-used/"$(basename "$f")$(date +%Y-%m-%d)"; done' sh {} +
或者,sh
根本沒有任何呼叫:
while IFS= read -r f; do
mv "$f" /tmp/big-not-used/"$(basename "$f")$(date +%Y-%m-%d)"
done < <(find / -size +100M -atime +30)
(後者假設檔名中沒有任何換行符。)
為了調試,您可能需要添加-v
(mv
如果支援的話)。