假设我有一个包含数千个文件的目录;如何打开名称同时包含字符串“red”和“green”的所有文件?
find . -type f -name '*red*' -name '*green*' -exec echo {} +
Run Code Online (Sandbox Code Playgroud)
替换echo为vi、gvim或less您想要用来打开文件的任何命令。
请注意,某些程序无法在命令行上处理多个文件名。如果您选择的程序是其中之一,请将+行末尾的 替换为\;。这将为每个文件名运行一次命令,而不是只对一长串文件名运行一次。
xdg-open就是这样一个命令。它会检测要求打开的文件类型,然后使用系统默认程序(如果您覆盖了默认程序,则使用您的首选程序)打开该文件。如果它无法识别文件的类型,它会询问您用什么打开它。
像这样使用它find有点有用,但同时又有点烦人。尝试一下,您就会明白为什么(您会看到许多窗口打开,一个接一个......每个匹配的文件名一个)。
find . -type f -name '*red*' -name '*green*' -exec xdg-open {} \;
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果您想查找与*red* OR *green*匹配的文件,则必须使用括号来指定“and”( -a) 和“or”( -o) 运算符的优先级。顺便说一句,当您find如上所述运行多个谓词时,默认运算符是 a -a,即谓词在逻辑上通过 AND 组合在一起。
括号对 shell 也有特殊含义,因此必须进行反斜杠转义,以便将它们传递给 find 命令而不是由 shell 解释。
find . -type f \( -name '*red*' -o -name '*green*' \) -exec echo {} +
Run Code Online (Sandbox Code Playgroud)
将其读作“常规文件 AND(文件名与‘*红色*’或‘*绿色*’匹配的文件名)”
zsh:set -o extendedglob # best in ~/.zshrc
ls -ld -- *green*~^*red*
Run Code Online (Sandbox Code Playgroud)
该~水珠操作是除(而不是)。^是为了不。所以组合是和不是,所以和。IOW,与相匹配的文件green在自己的名字,除了那些确实不包含red。
使用^否定运算符的替代方法(也需要extendedglob):
ls -ld -- ^(^*green*|^*red*)
Run Code Online (Sandbox Code Playgroud)
除了不包含绿色或不包含红色的文件之外的所有内容。
要还包括隐藏文件,请添加(D)glob 限定符。
您还可以使用 glob 限定符将文件名与正则表达式匹配,并且使用setopt rematchpcre,您可以将这些正则表达式设为 PCRE,您可以在其中使用前瞻运算符来实现和:
re() {
setopt localoptions rematchpcre
[[ $REPLY =~ $1 ]]
}
ls -ld -- *(e:'re "^(?=.*green).*red"':)
Run Code Online (Sandbox Code Playgroud)
或者:
re() {
setopt localoptions rematchpcre
[[ $REPLY =~ $RE ]]
}
RE='^(?=.*green).*red'; ls -ld -- *(+re)
Run Code Online (Sandbox Code Playgroud)
ksh或bash -O extglob或zsh -o kshglobls -ld -- !(!(*green*)|!(*red*))
Run Code Online (Sandbox Code Playgroud)
!(pattern)作为ksh等同zsh的^pattern扩展水珠运算符。
你也可以这样做:
ls -ld -- @(*green*red*|*red*green*)
Run Code Online (Sandbox Code Playgroud)
但这不能推广到任何模式。例如,对于包含abcand 的文件bcd,您需要@(*abc*bcd*|*abcd*|*bcd*abc*), 进行文件匹配???and *x*, @(x??|?x?|??x)...
ksh93ksh93有一些和通配符:
ls -ld -- @(*green*&*red*)
Run Code Online (Sandbox Code Playgroud)
或者使用其增强的正则~(A:...)表达式(与glob 运算符一起引入):
ls -ld -- ~(A:.*green.*&.*red.*)
Run Code Online (Sandbox Code Playgroud)
您还可以perl-like在ksh93以下内容中使用前瞻运算符:
ls -ld -- ~(P:(?=.*green).*red.*)
Run Code Online (Sandbox Code Playgroud)