显然有很多方法可以在 Linux 中完成相同的工作,但我最近需要for i in xxx
在树中递归地遍历每个项目的列表。我找到了一个tree
通过执行tree -fail
(或只是获取目录名称)的解决方案tree -faild
,但这让我想知道:是否可以通过仅使用来获得这样的列表ls
?
$ tree -fail
.
./.custom
./custom_loader.sh
./.git
./.git/branches
./.git/COMMIT_EDITMSG
./.git/config
./.git/description
./.git/HEAD
./.git/hooks
./.git/hooks/applypatch-msg.sample
答案1
shellbash
可以通过其特殊的**
通配模式递归到目录中。该**
模式与 类似 匹配*
,但也跨越/
路径名:
shopt -s globstar nullglob dotglob
for dirpath in ./**/; do
printf '%s\n' "$dirpath"
# whatever other code needs to be run on "$dirpath"
done
我可以globstar
访问,并且如果模式与任何内容都不匹配,**
我也nullglob
可以完全跳过循环,并且还可以查看隐藏文件。dotglob
该模式./**/
将匹配当前目录中或当前目录下的任何目录,就像./*/
匹配当前目录中的任何目录一样。
使用./**/*
或./**
列出所有类型的文件。
您还可以使用以下命令便携式地执行此操作find
:
find . -type d -exec sh -c '
for dirpath do
printf "%s\n" "$dirpath"
# whatever other code needs to be run on "$dirpath"
done' sh {} +
在这里,为脚本find
中的循环提供sh -c
目录的路径名。
运行这两个示例时您将看到的唯一区别是第一个示例(bash
带有 的循环**
)将解析到目录的符号链接,而find
不会解析到目录的符号链接。
如果您只想列出目录,那么该find
示例可能会大大缩短为
find . -type d -print
使用-type f
代替只能-type d
查看常规文件,-type
完全删除测试可以查看所有类型的文件。
显然,您也可以用来ls
获取这样的列表,但我并没有像您那样真正看到它的意义ls
除了查看输出之外什么也做不了。
shopt -s globstar dotglob
ls -1d ./**
请注意,如果模式扩展到的路径名列表太长,则此命令存在触发“参数列表太长”错误的风险。此答案中的其他命令都没有这个问题。
另请注意,这里实际上并没有ls
进行任何递归,而是 shell 扩展了递归模式,并且它甚至为调用之前./**
创建了参数列表。ls
ls