我想要做以下事情。我有如下的 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
文件的目录并保留包含此类文件的目录以及该目录的其他内容,我建议采用两步方法:
列出所有文件和目录并安全地保存到文本文件中
find . -depth -mindepth 1 > all
列出需要保留的目录(仅查找文件和打印目录)
find . -depth -name '*50000*' printf '%h\n' > keep
选择可删除的文件和目录,并倒
grep
grep -vf keep all > deletable
使用此列表进行删除(仅为示例)
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 *