Kir*_*ira 10 shell regular-expression wildcards
我在这里遇到了一个非常微不足道的问题:如何使*bash 中的符号表示零或更多,就像在诸如sed? 之类的工具中一样?
例如,ak*应该匹配名称完全由a后跟零个或多个ks组成的任何文件。它的扩张将包括a,ak,akk,和akkk,但不会akc。
我已经unsetopt sh_glob在 zsh 和set -o noglobbash 中尝试过;他们没有产生预期的行为。
Gil*_*il' 12
除了ksh93,通常的 shell 都没有与 sed、awk 等语法相同的正则表达式,可用于匹配文件。
Ksh93、bash 和 zsh 的正则表达式具有不同的语法,可向后兼容 globs:
?匹配任何单个字符(就像.通常的正则表达式语法)[…] 以几乎相同的方式匹配字符集*(FOO)匹配任意次数的FOO(就像在通常的正则表达式语法中一样)(FOO)*+(FOO)?(FOO)@(FOO|BAR)匹配FOO或BAR*开头和结尾此语法需要使用shopt -s extglobin bash 和setopt ksh_globin zsh激活。所以在 bash 你会写
shopt -s extglob
ls a*(k)
Run Code Online (Sandbox Code Playgroud)
ksh93、zsh 和bash 可以用construct的=~操作符对字符串进行正则表达式与扩展正则表达式(基本上是awk 的语法)的匹配[[ … ]]。虽然这不方便列出文件,但如果你真的想要它,它可以完成。
shopt -s dotglob # <<< include dot files, for bash
setopt globdots # <<< include dot files, for zsh
FIGNORE='@(.|..)' # <<< include dot files, for ksh
for x in *; do
if [[ $x =~ ^ak*$ ]]; then
…
fi
done
Run Code Online (Sandbox Code Playgroud)
ls ak{k,}将显示以开头的文件,ak后跟另一个k或什么都不显示。
$ touch ak akk akc
$ ls -l ak{k,}
-rw-rw-r-- 1 cas cas 0 Oct 27 10:30 ak
-rw-rw-r-- 1 cas cas 0 Oct 27 10:30 akk
Run Code Online (Sandbox Code Playgroud)
globs 不是正则表达式,但它们不仅仅是*and ?。
如果要使用正则表达式查找匹配的文件名,可以使用以下find命令:
$ find . -maxdepth 1 -type f -regex './ak+$'
./ak
./akk
Run Code Online (Sandbox Code Playgroud)
该-maxdepth 1选项将搜索限制为仅当前目录(不会搜索子目录)
如果您想要不区分大小写的搜索,请使用-iregex而不是-regex。
有许多方法可以使用find在其他命令中找到的文件。例如:
find . -maxdepth 1 -type f -regex './ak+$' -ls
find . -maxdepth 1 -type f -regex './ak+$' -exec ls -ld {} +
find . -maxdepth 1 -type f -regex './ak+$' -print0 | xargs -0r ls -ld
ls -ld $(find . -maxdepth 1 -type f -regex './ak+$')
Run Code Online (Sandbox Code Playgroud)
最后一个例子容易出现各种失败模式,包括 1. 不处理文件名中的空格等,2. 命令行长度限制。不建议。