使用 mv 移動到另一個目錄並立即重新命名

使用 mv 移動到另一個目錄並立即重新命名

我想知道每個+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)' \;

為了進行測試,您可以替換mvecho 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)

(後者假設檔名中沒有任何換行符。)

為了調試,您可能需要添加-vmv如果支援的話)。

相關內容