如何在 Bash 中打开或列出名称与两个模式匹配的所有文件

Jam*_*iro 2 bash wildcards

假设我有一个包含数千个文件的目录;如何打开名称同时包含字符串“red”和“green”的所有文件?

cas*_*cas 5

find . -type f -name '*red*' -name '*green*'  -exec echo {} +
Run Code Online (Sandbox Code Playgroud)

替换echovigvimless您想要用来打开文件的任何命令。

请注意,某些程序无法在命令行上处理多个文件名。如果您选择的程序是其中之一,请将+行末尾的 替换为\;。这将为每个文件名运行一次命令,而不是只对一长串文件名运行一次。

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(文件名与‘*红色*’或‘*绿色*’匹配的文件名)”


Sté*_*las 5

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)

kshbash -O extglobzsh -o kshglob

ls -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)...

ksh93

ksh93有一些通配符:

ls -ld -- @(*green*&*red*)
Run Code Online (Sandbox Code Playgroud)

或者使用其增强的正~(A:...)表达式(与glob 运算符一起引入):

ls -ld -- ~(A:.*green.*&.*red.*)
Run Code Online (Sandbox Code Playgroud)

您还可以perl-likeksh93以下内容中使用前瞻运算符:

ls -ld -- ~(P:(?=.*green).*red.*)
Run Code Online (Sandbox Code Playgroud)