我想找到驻留在任何目录中的所有文件foo
。例如,考虑以下文件:
foo/w
a/foo/x
a/b/foo/y
a/b/c/foo/z
a/b/c/foo/bar/n
Run Code Online (Sandbox Code Playgroud)
我想找到这些文件w,x,y,z
并将它们列在上面,即它们的相对路径。我的尝试是这样的
foo/w
a/foo/x
a/b/foo/y
a/b/c/foo/z
a/b/c/foo/bar/n
Run Code Online (Sandbox Code Playgroud)
这不起作用。搜索不应包括 file n
,即仅包含foo
我们感兴趣的父目录命名的文件。
不使用find
,而是在zsh
shell 中通配符:
$ printf '%s\n' **/foo/*(^/)
a/b/c/foo/z
a/b/foo/y
a/foo/x
foo/w
Run Code Online (Sandbox Code Playgroud)
这使用**
glob,它“递归地”匹配到目录中,匹配foo
当前目录或下面命名的任何目录,然后*(^/)
匹配这些foo
目录中的任何文件。的(^/)
在其端部是一个水珠限定符限制从匹配的目录的模式(使用(.)
匹配常规文件,或只(-.)
为还包括符号链接规则文件)。
在bash
:
shopt -s globstar nullglob
for pathname in **/foo/*; do
if [[ ! -d "$pathname" ]] || [[ -h "$pathname" ]]; then
printf '%s\n' "$pathname"
fi
done
Run Code Online (Sandbox Code Playgroud)
我将nullglob
选项设置为bash
完全删除模式,以防它不匹配任何内容。该globstar
外壳选项允许使用的**
中bash
(这是由默认启用zsh
)。
由于bash
没有 glob 限定符zsh
,我循环遍历模式匹配的路径名并测试每个匹配项以确保它在打印之前不是目录。将 " ! -d || -h
" 测试更改为 " " 测试以-f && ! -h
仅选择常规文件,或者仅选择单个 " -f
" 测试以打印到常规文件的符号链接。