是否可以ls
使用 bash 通过简单的命令来实现以下目标。列出以两个字母开头、e
名称中包含 且以一个1
或多个字母结尾的所有文件。如果是这样,命令是什么以及是否需要启用扩展通配符?
答案1
ls
与文件名不匹配(除非您想考虑--include
/等 GNU 扩展名--exclude
)。通常用于此目的的是 shell glob。
ls -ld [[:alpha:]][[:alpha:]]*e*[[:alpha:]]
会找到符合这些要求的文件,但会错过ee
例如。你可以这样做:
桀骜
使用并不是/除了运算符 ( ~
) 和不是( ^
):
setopt extendedglob
ls -ld [[:alpha:]](#c2)*~^*e*~^*[[:alpha:]]
或者使用perl
类似前瞻正则表达式运算符:
setopt rematchpcre
match() [[ $REPLY =~ '^(?=.*e)(?=.*[[:alpha:]]$)[[:alpha:]][[:alpha:]]' ]]
ls -ld *(+match)
克什93
使用&
内部@(...)
:
ls -ld @([[:alpha:]][[:alpha:]]*&*e*&*[[:alpha:]])
与其相同增强正则表达式(使用 启用~(X:...)
):
ls -ld ~(X:[[:alpha:]][[:alpha:]].*&.*e.*&.*[[:alpha:]])
或者使用类似 perl 的前瞻运算符:
ls -ld ~(P:(?=.*e)(?=.*[[:alpha:]]$)[[:alpha:]][[:alpha:]])*
巴什
bash
没有和运算符,但当启用ksh
该选项时,它确实支持 's 运算符的子集,因此您可以执行以下操作:extglob
shopt -s extglob
ls -ld @([[:alpha:]]?([[:alpha:]]*)e?(*[[:alpha:]])|e[[:alpha:]]?(*[[:alpha:]]))
@(x|y)
(如zsh
)(x|y)
是一个或者操作员。?(x)
是可选的x
(就像zsh
's (x|)
;@(x|)
也适用于ksh
/ bash
)。
另一个技巧是利用这样的事实“A和B”是“不(不(A)或不(B))”,并且 so 支持的 ksh glob 子集bash
恰好包括不是和或者运算符,因此您可以执行以下操作:
ls -ld !(!([[:alpha:]][[:alpha:]]*)|!(*e*)|!(*[[:alpha:]]))
这些操作符也可以在这些操作符最初来源的地方工作ksh
(所有变体,不存在)。shopt
非基于全局的方法
和find
:
find . ! -name . -prune -name '[[:alpha:]][[:alpha:]]*' \
-name '*e*' \
-name '*[[:alpha:]]' -exec ls -ld {} +
(请注意,文件列表不会被排序,并且包含不构成有效字符的字节的文件名将被排除;文件名也会以 为前缀./
)。