Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 删除除最后一个匹配项以外的所有项_Bash_Find - Fatal编程技术网

Bash 删除除最后一个匹配项以外的所有项

Bash 删除除最后一个匹配项以外的所有项,bash,find,Bash,Find,我想删除目录中每个文件夹中与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 ... 等等。在每个子文件夹中,我只想保留

我想删除目录中每个文件夹中与
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
    ...
等等。在每个子文件夹中,我只想保留最后一个匹配的文件,因此对于
文件夹1
,这将是
文件2-1
,而在
文件夹2中,它将是
文件2-2
。每个子文件夹中的文件数通常不同

因为我有一个非常嵌套的文件夹结构,所以我考虑过像这样使用
find
命令

find . -type f -name "file*" -delete_all_but_last_match
我知道如何删除所有匹配项,但不知道如何排除最后一个匹配项

我还发现了以下代码:

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

find . -type f -name "file*" -print0 | head -zn-1 | xargs -0 rm -rf
在大多数情况下,它会删除所有匹配项,只有在某些情况下,最后一个文件被保留。所以它对我不起作用,可能是因为每个文件夹中的文件数量不同

编辑:


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

使用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-键入f-name“file*”| awk-f/'{map1[$(NF-1)]++;map[$(NF-1)][map1[$(NF-1)]]=$0}END{for(i in map){for(j=1;j
#!/bin/bash
shopt-s环球之星
对于**/中的dir;do
文件=(“$dir”文件*)
取消设置“文件[-1]”
rm“${files[@]}”
完成

Yes
file
是文件名中的一个文本字符串。只有具有此字符串的文件才会受到影响。如果我的字词选择令人困惑,很抱歉。不,
stuff
应该保留。
 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