给出的是(子)目录中与字符串匹配的一组文件,例如:
find -name 'string' | sort
./1/2/3/4/string
./1/2/3/string
./1/2/string
./1/string
./string
为什么使用globstar
来匹配文件,如
ls **string
string
无法运行目录,同时
ls **/string
1/2/3/4/string 1/2/3/string 1/2/string 1/string string
成功了吗?根据我对页面描述的理解,man
它应该匹配(子)目录,不是吗?
像这样的问题通常被标记为重复“ls * 、 ls ** 和 ls *** 的结果”,但那里的答案只处理ls **
,它确实通过目录递归。似乎双星号后跟字符串会中断globstar
。
运行GNU bash v.4.4.19(1)
于mint 19
从man bash
环球星
如果设置,路径名扩展上下文中使用的模式 ** 将匹配所有文件以及零个或多个目录和子目录。如果模式后跟 /,则仅目录和子目录匹配。
答案1
这在 Ksh 和 Zsh 中也是如此。
$ mkdir -p a/b/cdir
$ touch a/b/cfile
$ ksh -c 'set -o globstar; echo **c*'
**c*
$ zsh -c 'echo **c*'
zsh:1: no matches found: **c*
在模式匹配下,Bash 的手册说:
当
globstar
启用 shell 选项并*
在文件名扩展上下文中使用时,*
用作单个模式的两个相邻 s 将匹配所有文件以及零个或多个目录和子目录。
我想这可以理解为“单个模式”是由斜杠分隔的部分,因此foo/**/bar
它处于单个模式中,但**bar
事实并非如此。
不过,这可能会更清楚。
整个模式后面的尾部斜杠使模式仅匹配目录:
$ echo **/c*/
a/b/cdir/
答案2
当不受(仅)限制时,双精度*
衰减到一的效果:*
/
$ ls *c
abc ac acc bc cc dc
$ ls **c
abc ac acc bc cc dc
任何不是 a 的前导或尾随字符/
都会导致**
衰减:
这只是因为路径名(作为文件名)可以不是包含任何/
.
a 不可能*
扩展为包含 的名称/
。 A**
有点类似,它会扩展为包含以下内容的字符串/
仅有的/
当单独或由(不是任何其他字符/字符串)分隔时:
$ ls -d ./** | sort
./
./1
./1/2
./1/2/3
./1/2/3/4
./1/2/3/4/string
./1/2/3/string
./1/2/string
./1/string
./abc
./ac
./acc
./bc
./cc
./dc
./string
$ ls -d ./**c | sort
./abc
./ac
./acc
./bc
./cc
./dc
$ ls -d ** | sort
1
1/2
1/2/3
1/2/3/4
1/2/3/4/string
1/2/3/string
1/2/string
1/string
abc
ac
acc
bc
cc
dc
string
$ ls -d **c | sort
abc
ac
acc
bc
cc
dc
$ ls -d **/ | sort
1/
1/2/
1/2/3/
1/2/3/4/
$ ls -d 1**/ | sort
1/