如何查找具有特定扩展名的文件,同时仅排除当前目录中的某些名称?

如何查找具有特定扩展名的文件,同时仅排除当前目录中的某些名称?

我想要寻找一些文件,在非 GNU 环境中

  • 仅在当前目录中
  • 带扩展*.ext1*.ext2,
  • 但不是姓名1.*或者名称2.*

以下命令有效,但可能效率不高,因为 shell 会扩展./*寻找可以获得大量的文件和目录列表。

find ./* -prune \( -name '*ext1' -o -name '*ext2' \) -a ! \( -name 'name1*' -o -name 'name2*' \)

更新:

我在AIX上工作,没有-最大深度选项。

答案1

find

find . ! -name . -prune \
    \( -name '*.ext1' -o -name '*.ext2' \) \
  ! \( -name 'name1.*' -o -name 'name2.*' \)

using-prune是 GNU 的标准等效项-maxdepth。这里它告诉find不要下降到除 之外的任何目录中.

使得它也从选择中! -name .排除, GNU 的标准等效项也是如此。对于 GNU ,你可以写..! -name . -prune-mindepth 1 -maxdepth 1-mindepth 1find . \( -name . -o -prune \)

使用zsh,您还可以做到:

set -o extendedglob
print -rC1 -- *.(ext1|ext2)~(name1|name2).*(ND)

~是与非运算符,并(D)包含点文件。

答案2

在当前目录中,您可以使用lswith grep(假设您的文件名不包含换行符):

ls -a | grep -E '\.ext(1|2)$' | grep -vE '^name(1|2)\.'

答案3

“仅在当前目录中”您不需要find文件,您可以简单地列出它们(关于可能遇到奇怪的文件名,包含有趣的字符的常见警告):

ls -d *.ext1 *.ext2 2>/dev/null | grep -v '^\(name1\|name2\)\.'

答案4

既然你有 bash 可用,你可以使用它扩展模式匹配

shopt -s extglob
files=( !(name1|name2).@(ext1|ext2) )

这表示:当前目录中的所有文件不是以“name1”或“name2”开头,后跟句点,然后是任何一个“ext1”或“ext2”。

对于示例运行:

$ touch name1.ext1 name1.ext2 name2.ext1 name2.ext2 name3.ext1 name3.ext2 name3.ext3
$ files=( !(name1|name2).@(ext1|ext2) )
$ declare -p files
declare -a files='([0]="name3.ext1" [1]="name3.ext2")'

请注意,如果您有一个简单的文件名,例如“name3.ext2”,则必须选择在何处放置模式匹配的句点 - 要么在“name3”中。或者在“.ext2”中;如果您有更长的文件名,例如“name3.intermediate.ext2”,那么您可以在中间使用点和一个全局符号:

$ files=( !(name1|name2).*.@(ext1|ext2) )

相关内容