我遇到這種情況,不同的子資料夾中有很多名稱相似的檔案(但它們都遵循某種模式)
file1
file1 (Copy)
/folder1/file2.txt
/folder1/file2 (Copy).txt
/folder1/file3.png
/folder1/file3 (Copy).png
每個檔案都位於其副本的同一資料夾中,並且具有相同的副檔名,不同之處在於它(Copy)
在名稱末尾
我想獲取所有這些文件並刪除最舊的一個,然後最終將文件重命名為,例如,如果需要重命名,則將其重命名file1 (Copy)
為file1
(即刪除後綴)。(Copy)
我正在考慮使用find
andmv
但我不知道如何告訴它移動最近的一個。
答案1
擴充find
+bash
解決方案(還需要 GNU 實作stat
):
find . -type f -name "* (Copy).*" -exec bash -c 'p="${0%/*}"; bn="${0##*/}";
main_bn="${bn/ (Copy)/}";
if [ -f "$p/$main_bn" ]; then
t_copy_file=$(stat -c %Y "$0"); t_main_file=$(stat -c %Y "$p/$main_bn");
if [[ $t_copy_file -gt $t_main_file ]]; then
mv "$0" "$p/$main_bn";
else
rm "$0";
fi;
fi' {} \;
p="${0%/*}"
- 基本名稱被修剪的檔案路徑/路徑bn="${0##*/}"
- 文件的基本名稱main_bn="${bn/ (Copy)/}"
-(Copy)
從基本名稱中刪除子字串以獲得主要/公共基本名稱if [ -f "$p/$main_bn" ]
- 如果主要/原始文件存在(並且在符號連結解析後發現是常規文件)t_copy_file=$(stat -c %Y "$0")
- 取得找到的最後修改時間“複製”文件t_main_file=$(stat -c %Y "$p/$main_bn")
- 取得最後修改時間原來的文件if [[ $t_copy_file -gt $t_main_file ]]
- 如果“複製”文件是最近的文件 - 將其移至原來的一個(使它原來的) 和mv "$0" "$p/$main_bn"
- 否則 - 的原來的文件是最新的,刪除“複製“ 文件與
rm "$0"
-nt
或使用檔案測試運算子更短一些( [ newerfile –nt olderfile ]
- 檢查是否newerfile
比 更晚更改olderfile
,或是否newerfile
存在且不olderfile
存在):
find . -type f -name "* (Copy).*" -exec bash -c 'p="${0%/*}"; bn="${0##*/}";
main_bn="${bn/ (Copy)/}";
if [ -f "$p/$main_bn" ]; then
if [ "$0" -nt "$p/$main_bn" ]; then
mv "$0" "$p/$main_bn";
else
rm "$0";
fi;
fi' {} \;
答案2
使用以下方法可能會更容易zsh
:
setopt extendedglob # best in ~/.zshrc
for file (./**/?*" (Copy)"*(ND.)) {
base=$file:h/${${file:t}/" (Copy)"}}
[[ ! -f $base || -L $base ]] ||
if [ $file -nt $base ]; then
mv $file $base
else
rm -f $file
fi
}
您可能需要先檢查是否沒有file (Copy) (Copy).txt
文件。
**/
: 任意等級的子目錄N
:空球如果沒有符合則展開為空而不是出錯D
:包括隱藏檔案(D
ot 檔案)並下降到隱藏目錄。.
: 只包含常規的檔案(無目錄、fifo、裝置、符號連結...)$file:h
:頭文件(目錄部分)的,如csh
$file:t
:尾巴(檔案名稱部分)${var/pattern/replacement}
,這裡沒有替換[[ ! -f $base || -L $base ]] ||...
跳過非常規文件或符號連結(即使它們指向常規文件)作為保護措施。[ $file -nt $base ]
$file
: 如果最後修改則回傳 true後$base
(或$base
無法訪問,我們不應該在上述檢查之後發生)。