列出名称满足 3 个不同条件的文件

dam*_*ant 2 linux bash debian

是否可以ls通过使用 bash的简单命令实现以下目标。列出所有以两个字母开头、e名称中有一个、以一个1或多个字母结尾的文件。如果是这样,命令是什么,是否需要启用扩展通配符?

Sté*_*las 5

ls不匹配文件名(除非你想考虑像--include/ 的GNU 扩展名--exclude)。这是通常用于此目的的外壳球。

ls -ld [[:alpha:]][[:alpha:]]*e*[[:alpha:]]
Run Code Online (Sandbox Code Playgroud)

会找到符合这些要求的文件,但会错过ee例如。你可以这样做:

zsh

使用AND NOT / EXCEPT运算符 ( ~) 和NOT ( ^):

setopt extendedglob
ls -ld [[:alpha:]](#c2)*~^*e*~^*[[:alpha:]]
Run Code Online (Sandbox Code Playgroud)

或者使用perl-like look forward 正则表达式运算符:

setopt rematchpcre
match() [[ $REPLY =~ '^(?=.*e)(?=.*[[:alpha:]]$)[[:alpha:]][[:alpha:]]' ]]
ls -ld *(+match)
Run Code Online (Sandbox Code Playgroud)

ksh93

使用&内部@(...)

ls -ld @([[:alpha:]][[:alpha:]]*&*e*&*[[:alpha:]])
Run Code Online (Sandbox Code Playgroud)

与其增强的正则表达式相同(使用 启用~(X:...)):

ls -ld ~(X:[[:alpha:]][[:alpha:]].*&.*e.*&.*[[:alpha:]])
Run Code Online (Sandbox Code Playgroud)

或者使用类似 perl 的前瞻运算符:

ls -ld ~(P:(?=.*e)(?=.*[[:alpha:]]$)[[:alpha:]][[:alpha:]])*
Run Code Online (Sandbox Code Playgroud)

猛击

bash没有AND运算符,但kshextglob启用该选项时它确实支持's 运算符的子集,因此您可以执行以下操作:

shopt -s extglob
ls -ld @([[:alpha:]]?([[:alpha:]]*)e?(*[[:alpha:]])|e[[:alpha:]]?(*[[:alpha:]]))
Run Code Online (Sandbox Code Playgroud)

@(x|y)(如zsh's (x|y))是一个OR运算符。?(x)是可选的x(如zsh's (x|);@(x|)也适用于ksh/ bash)。

另一个技巧是利用"A 和 B""not(not(A) or not(B))"的事实,并且bashso支持的 ksh glob 的子集恰好包含not and or运算符,因此您可以这样做:

ls -ld !(!([[:alpha:]][[:alpha:]]*)|!(*e*)|!(*[[:alpha:]]))
Run Code Online (Sandbox Code Playgroud)

这些操作符也适用于ksh(所有变体,没有shopt)这些操作符最初来自的地方。

非基于全局的方法

find

find . ! -name . -prune -name '[[:alpha:]][[:alpha:]]*' \
                        -name '*e*' \
                        -name '*[[:alpha:]]' -exec ls -ld {} +
Run Code Online (Sandbox Code Playgroud)

(注意文件列表不会被排序,包含不构成有效字符的字节的文件名将被排除;文件名也将以 为前缀./)。