【问题标题】:delete all but the last match删除除最后一场比赛外的所有比赛
【发布时间】:2021-02-24 13:15:54
【问题描述】:

我想删除目录中每个文件夹中存在的与file* 匹配的一组文件中的最后一个匹配项之外的所有匹配项。

例如:

Folder 1
    file
    file_1-1
    file_1-2
    file_2-1
    stuff.txt
    stuff
Folder 2
    file_1-1
    file_1-2
    file_1-3
    file_2-1
    file_2-2
    stuff.txt
Folder 3
    ...

等等。在每个子文件夹中,我只想保留最后一个匹配的文件,所以对于Folder 1,这将是file_2-1,在Folder 2 中它将是file_2-2。每个子文件夹中的文件数量通常不同。

因为我有一个非常隐蔽的文件夹结构,所以我想以某种方式使用find 命令

find . -type f -name "file*" -delete_all_but_last_match

我知道如何删除所有匹配项,但不知道如何排除最后一个匹配项。

我还发现了以下一段代码:

https://askubuntu.com/questions/1139051/how-to-delete-all-but-x-last-items-from-find

但是当我将修改后的版本应用到测试文件夹时

find . -type f -name "file*" -print0 | head -zn-1 | xargs -0 rm -rf

在大多数情况下,它会删除所有匹配项,仅保留最后一个文件。所以它对我不起作用,大概是因为每个文件夹中的文件数量不同。

编辑:

这些文件夹不包含其他子文件夹,但它们通常位于几个子文件夹级别的末尾。因此,如果脚本也可以在上面的某些级别上执行,那将是一个好处。

【问题讨论】:

  • file 是文件名中的文字字符串。只有具有此字符串的文件才会受到影响。对不起,如果我选择的词令人困惑。
  • 不,stuff 应该保留。

标签: bash find


【解决方案1】:
#!/bin/bash
shopt -s globstar
for dir in **/; do 
    files=("$dir"file*)
    unset 'files[-1]'
    rm "${files[@]}"
done

【讨论】:

    【解决方案2】:

    使用 awk 和 xargs 尝试以下解决方案:

     find . -type f -name "file*" | awk -F/ '{ map1[$(NF-1)]++;map[$(NF-1)][map1[$(NF-1)]]=$0 }END { for ( i in map ) { for (j=1;j<=(map1[i]-1);j++) { print "\""map[i][j]"\"" } } }' | xargs rm
    

    解释:

     find . -type f -name "file*" | awk -F/ '{                               # Set the field delimiter to "/" in awk
          map1[$(NF-1)]++;                                     # Create an array map1 with the sub-directory as the index and an incrementing counter the value (number of files in each sub-directory)
          map[$(NF-1)][map1[$(NF-1)]]=$0                       # Create a two dimentional array with the sub directory index one and the file count the second. The line the value
       }
    END { 
          for ( i in map ) { 
            for (j=1;j<=(map1[i]-1);j++) { 
               print "\""map[i][j]"\""                         # Loop through the map array utilising map1 to get the last but one file and printing the results
            } 
          } 
        }' | xargs rm                                     # Run the result through xargs rm
    

    删除 xargs 的管道以验证文件是否按预期列出,然后再重新添加以实际删除文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-05
      • 2015-09-16
      • 1970-01-01
      • 1970-01-01
      • 2021-05-18
      • 1970-01-01
      • 2021-08-24
      相关资源
      最近更新 更多