是否可以ls
通过使用 bash的简单命令实现以下目标。列出所有以两个字母开头、e
名称中有一个、以一个1
或多个字母结尾的文件。如果是这样,命令是什么,是否需要启用扩展通配符?
ls
不匹配文件名(除非你想考虑像--include
/ 的GNU 扩展名--exclude
)。这是通常用于此目的的外壳球。
ls -ld [[:alpha:]][[:alpha:]]*e*[[:alpha:]]
Run Code Online (Sandbox Code Playgroud)
会找到符合这些要求的文件,但会错过ee
例如。你可以这样做:
使用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)
使用&
内部@(...)
:
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运算符,但ksh
在extglob
启用该选项时它确实支持'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))"的事实,并且bash
so支持的 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)
(注意文件列表不会被排序,包含不构成有效字符的字节的文件名将被排除;文件名也将以 为前缀./
)。