How to recursively list subdirectories in Bash without using “find” or “ls” commands?
我知道你可以使用
你只要用贝壳就行了
1 2 3 4 5 6 7 8 9 10 11 12 13 | #!/bin/bash recurse() { for i in"$1"/*;do if [ -d"$i" ];then echo"dir: $i" recurse"$i" elif [ -f"$i" ]; then echo"file: $i" fi done } recurse /path |
或者如果你有bash 4.0
1 2 3 4 5 6 | #!/bin/bash shopt -s globstar for file in /path/** do echo $file done |
试用使用
1 | tree -d |
下面是一个可能的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # my_ls -- recursively list given directory's contents and subdirectories # $1=directory whose contents to list # $2=indentation when listing my_ls() { # save current directory then cd to"$1" pushd"$1">/dev/null # for each non-hidden (i.e. not starting with .) file/directory... for file in * ; do # print file/direcotry name if it really exists... test -e"$file" && echo"$2$file" # if directory, go down and list directory contents too test -d"$file" && my_ls"$file""$2 " done # restore directory popd >/dev/null } # recursively list files in current # directory and subdirectories my_ls . |
作为一个练习,您可以考虑如何修改上述脚本以打印文件的完整路径(而不是缩进的文件/目录名),可能会去掉进程中的
顺便说一句,注意使用
去掉
删除
同时列出隐藏文件(如
1 2 3 4 5 6 7 8 | ... for file in * .?* ; do if ["$file" !=".." ] ; then test -e ... test -d ... fi done ... |
注意使用EDOCX1(字符串比较)而不是EDOCX1(数字比较)。
另一种技术是生成子层,而不是使用
1 2 3 4 5 6 7 8 9 10 | my_ls() { # everything in between roundbrackets runs in a separatly spawned sub-shell ( # change directory in sub-shell; does not affect parent shell's cwd cd"$1" for file in ... ... done ) } |
注意,在一些shell实现中,对于可以作为参数传递给
Since it is for bash, it is a surprise that this hasn't been already said:
(globstar valid from bash 4.0+)
1 2 | shopt -s globstar nullglob dotglob echo **/*/ |
这就是全部。尾随斜线
选项
正如MarkByers所说,您可以使用
应用递归就完成了。
不过,我不确定是否有人提到空目录
基于此答案;使用外壳选项实现所需的全局绑定行为:
- 使用
globstar 启用** (bash 4.0或更新版本) - 使用
dotglob 包含隐藏目录 - 如果与
nullglob 不匹配,则扩展到空字符串而不是**/*/ 。
然后将
1 2 3 | shopt -s globstar dotglob nullglob printf '%q ' **/*/ |
因此,如果您有像
1 2 3 4 5 | $ printf '%q ' **/*/ $'has newline/' has\ space/ |
每行一个目录。
从技术上讲,find2perl perl或file::find都不直接使用find和ls。
1 2 3 4 5 6 7 8 9 10 11 12 | $ find2perl -type d | perl $ perl -MFile::Find -e'find(sub{-d&&print"$File::Find::name <div class="suo-content">[collapse title=""]<ul><li>但是,如果是这样的话,使用python/ruby/php等任何可以列出文件的语言在技术上都不会使用<wyn>ls</wyn>或<wyn>find</wyn>。</li><li>@鬼狗74显然。但是,由于所有严肃的回答都得到了不那么惊人的反馈,这是一个…不太严重。(我本来打算用C语言编写一个<wyn>find</wyn>的克隆版本,然后编写一个shell脚本,编译+运行它,但我觉得这太费劲了,不适合开玩笑。)</li></ul>[/collapse]</div><hr>[cc lang="bash"]$ function f { for i in $1/*; do if [ -d $i ]; then echo $i; f $i; fi; done } $ mkdir -p 1/2/3 2/3 3 $ f . ./1 ./1/2 ./1/2/3 ./2 ./2/3 ./3 |