删除文件名中包含特定字符串但不包含其他字符串的文件

删除文件名中包含特定字符串但不包含其他字符串的文件

我有一些目录,其中包含大量文件。我希望通过删除其中包含特定字符串但不包含某些其他字符串的文件来修剪这些目录。

例如,删除文件名中包含“AAA”但不包含“BBB”、“CCC”或“DDD”的文件。

这可能吗?

答案1

find从您希望在其中递归搜索要删除的文件的某个顶级目录中使用:

find . -type f -name '*AAA*' ! -name '*BBB*' ! -name '*CCC*' ! -name '*DDD*' -print

上面将找到当前目录中或当前目录下的所有常规文件。在这些文件中,它将选择名称包含 的文件AAA,取消选择名称包含BBB,CCC或 的文件DDD(每个文件!都会否定紧随其后的测试),然后打印仍然选定的文件的路径名。

这里使用的模式是普通的文件名匹配模式(不是正则表达式)。需要用引号引起来以避免意外匹配当前目录中的名称。

要删除文件,请更改-print-delete.

由于-delete是一个非标准谓词(尽管是普遍实现的谓词),-exec rm {} +因此使用它会更便携。这将rm一次执行尽可能多的选定文件。


一般来说,有两个要包含和排除的模式列表,假设bash为 shell,并假设文件名应与任何包含模式匹配,并且不与任何排除模式匹配:

include=( '*AAA*' '*123*' )
exclude=( '*BBB*' '*CCC*' '*DDD*' )

or_filter=()
and_filter=()

for pattern in "${include[@]}"; do
    or_filter+=( -o -name "$pattern" )
done
or_filter=( "${or_filter[@]:1}" )  # remove initial -o

for pattern in "${exclude[@]}"; do
    and_filter+=( ! -name "$pattern" )
done

find . -type f \( "${or_filter[@]}" \) "${and_filter[@]}" -print

相关内容