我想要寻找一些文件,在非 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 1
find . \( -name . -o -prune \)
使用zsh
,您还可以做到:
set -o extendedglob
print -rC1 -- *.(ext1|ext2)~(name1|name2).*(ND)
~
是与非运算符,并(D)
包含点文件。
答案2
在当前目录中,您可以使用ls
with 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) )