假设我有一个包含数千个文件的目录;如何打开名称同时包含字符串“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 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)
但这不能推广到任何模式。例如,对于包含abc
and 的文件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-like
在ksh93
以下内容中使用前瞻运算符:
ls -ld -- ~(P:(?=.*green).*red.*)
Run Code Online (Sandbox Code Playgroud)