查找名称相似的文件,删除最旧的文件,重命名最新的文件

查找名称相似的文件,删除最旧的文件,重命名最新的文件

我遇到这种情况,不同的子文件夹中有很多名称相似的文件(但它们都遵循某种模式)

file1
file1 (Copy)
/folder1/file2.txt
/folder1/file2 (Copy).txt
/folder1/file3.png
/folder1/file3 (Copy).png

每个文件都位于其副本的同一文件夹中,并且具有相同的扩展名,不同之处在于它(Copy)在名称末尾

我想获取所有这些文件并删除最旧的一个,然后最终将文件重命名为,例如,如果需要重命名,则将其重命名file1 (Copy)file1(即删除后缀)。(Copy)

我正在考虑使用findandmv但我不知道如何告诉它移动最近的一个。

答案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或者使用文件测试运算符更短一些( [ new­er­file –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:包括隐藏文件(Dot 文件)并下降到隐藏目录。
  • .: 只包括常规的文件(无目录、fifo、设备、符号链接...)
  • $file:h:文件(目录部分)的,如csh
  • $file:t:尾巴(文件名部分)
  • ${var/pattern/replacement},这里没有替换
  • [[ ! -f $base || -L $base ]] ||...跳过非常规文件或符号链接(即使它们指向常规文件)作为保护措施。
  • [ $file -nt $base ]$file: 如果最后修改则返回 true $base(或者$base无法访问,我们不应该在上述检查之后发生)。

相关内容