删除所有不包含与 glob/regex 匹配的文件名的文件夹

删除所有不包含与 glob/regex 匹配的文件名的文件夹

我想要做以下事情。我有如下的 2 级文件层次结构:

A
| B
| | g
| | h50000
| C

其中 A、B、C 是文件夹。我想删除所有不包含与特定模式匹配的文件的文件夹(在我的例子中50000是模式,glob 样式)在深度级别 2 上。(在此示例中,应仅删除文件夹 C 及其内容,而保留 A)

在我的应用程序中,如果我删除所有子文件夹都不包含与模式匹配的文件名的文件夹,那就没问题了。(如果不指定要删除的深度,不删除 A 会更容易)。

我怎样才能在 Linux 机器上的 bash 中做到这一点?

答案1

find可以排除一个模式:

find \! -name '*50000*' -delete

!由于它在 shell 中使用,因此必须转义。

含有内容的目录将不会被删除。

警告:因为从你的问题来看我有点不清楚 - 这将删除具有模式的文件夹中的其他文件50000,例如A/B/g将被删除,并且只有具有名称的文件(和目录)50000(包括它们的父目录)会被保留!


为了删除所有没有50000文件的目录并保留包含此类文件的目录以及该目录的其他内容,我建议采用两步方法:

  1. 列出所有文件和目录并安全地保存到文本文件中

    find . -depth -mindepth 1 > all
    
  2. 列出需要保留的目录(仅查找文件和打印目录)

    find . -depth -name '*50000*' printf '%h\n' > keep
    
  3. 选择可删除的文件和目录,并倒grep

    grep -vf keep all > deletable
    
  4. 使用此列表进行删除(仅为示例)

    while read line 
    do
    
       find . -wholename "$line" -delete
    
    done < deletable
    

请注意,第 4 点由于是逐行执行的 shell 脚本,因此速度较慢。虽然不是最好的,但可以完成工作。


或者(更简单):如果您具有 root 访问权限,请中间更改 -attribute i,防止更改(包括删除),删除所有内容(因为不允许删除i-flag 的文件和目录),并i在最后删除标志。

#%h goes for parent directories of our hits
find -name '*5000*' -printf '%h\0' | xargs -0 chattr -R +i '{}'
#be careful now ....
rm -r *
chattr -i -R *

相关内容