Linux命令以树的形式打印目录结构

use*_*655 474 linux command-line

是否有任何linux命令可以从Bash脚本调用,该脚本将以树的形式打印目录结构,例如,

folder1
   a.txt
   b.txt
folder2
   folder3
Run Code Online (Sandbox Code Playgroud)

cra*_*fty 735

这是你在寻找,应该在大多数发行版(可能是一个可选的安装)?

~> tree -d /proc/self/
/proc/self/
|-- attr
|-- cwd -> /proc
|-- fd
|   `-- 3 -> /proc/15589/fd
|-- fdinfo
|-- net
|   |-- dev_snmp6
|   |-- netfilter
|   |-- rpc
|   |   |-- auth.rpcsec.context
|   |   |-- auth.rpcsec.init
|   |   |-- auth.unix.gid
|   |   |-- auth.unix.ip
|   |   |-- nfs4.idtoname
|   |   |-- nfs4.nametoid
|   |   |-- nfsd.export
|   |   `-- nfsd.fh
|   `-- stat
|-- root -> /
`-- task
    `-- 15589
        |-- attr
        |-- cwd -> /proc
        |-- fd
        | `-- 3 -> /proc/15589/task/15589/fd
        |-- fdinfo
        `-- root -> /

27 directories
Run Code Online (Sandbox Code Playgroud)

样本取自维护者网页.

您可以添加选项-L #,其中#由数字替换,以指定最大递归性水平.

删除-d以显示文件.

  • 注意任何访问者看到这个:删除`-d`也显示文件! (51认同)
  • 要在Mac OS X上安装w/Homebrew:`brew install tr​​ee` (39认同)
  • 注意任何访问者看到这个:手册页列出了一大堆更多标志给你:) (28认同)
  • 您可以使用[Homebrew](http://brew.sh/)在Mac OS X上安装它! (5认同)
  • 甚至 Ubuntu 16.04 也没有这个。使用 `apt-get install tr​​ee` 将安装它。 (4认同)
  • 要在cygwin`apt-cyg install tr​​ee`上安装(假设您已经安装了apt-cyg) (2认同)

Sou*_*sou 311

你可以用这个:

ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'
Run Code Online (Sandbox Code Playgroud)

它将在几秒钟内显示当前子目录的图形表示,没有文件,例如/var/cache/:

   .
   |-apache2
   |---mod_cache_disk
   |-apparmor
   |-apt
   |---archives
   |-----partial
   |-apt-xapian-index
   |---index.1
   |-dbconfig-common
   |---backups
   |-debconf
Run Code Online (Sandbox Code Playgroud)

资源

  • 用文件:`find.| sed -e"s/[^ - ] [^\/]*\// |/g"-e"s/| \([^] \)/ | - \1 /" (32认同)
  • 不打印文件. (31认同)
  • 如果你想要它有空格,更像是请求的OP,那么:`ls -R | grep":$"| sed -e's /:$ //'-e's/[^ - ] [^\/]*\///g'-e's/^//' (7认同)
  • @Ben 谢谢你,所有其他(非“树”)答案产生的结果对我来说看起来并不完全正确。例如,在这个答案中,应该有一行从“apt”向下,然后水平到“archives”,而不是从“.”向下并进入“archives”,只是因为更多的缩进,您可以猜测它实际上是`apt` 的子文件夹。所以你也可以把这些线条去掉,这样至少不会产生误导。 (2认同)

Pav*_*mar 36

此命令可同时显示文件夹和文件

find . | sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/"
Run Code Online (Sandbox Code Playgroud)

示例输出:

.
 |-trace.pcap
 |-parent
 | |-chdir1
 | | |-file1.txt
 | |-chdir2
 | | |-file2.txt
 | | |-file3.sh
 |-tmp
 | |-json-c-0.11-4.el7_0.x86_64.rpm
Run Code Online (Sandbox Code Playgroud)

来源:来自@javasheriff 的评论在这里。它作为评论被淹没并作为答案发布有助于用户轻松发现它。

  • 这是一个很大的帮助,因为我们没有在某个服务器上安装树。这很可能适用于任何标准 Linux 系统。 (2认同)

use*_*026 20

由于这是一个成功的评论,我将其添加为答案:
以树的形式打印目录结构,
WITH FILES

 find . | sed -e "s/[^-][^\/]*\//  |/g" -e "s/|\([^ ]\)/|-\1/" 
Run Code Online (Sandbox Code Playgroud)

  • 如果您想对结果列表进行排序,请按以下方式将上面的好解决方案与“sort”结合起来:“find”。| 排序| sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/" ` (5认同)

Rus*_*art 16

要将Hassou的解决方案添加到.bashrc,请尝试:

alias lst='ls -R | grep ":$" | sed -e '"'"'s/:$//'"'"' -e '"'"'s/[^-][^\/]*\//--/g'"'"' -e '"'"'s/^/   /'"'"' -e '"'"'s/-/|/'"'"
Run Code Online (Sandbox Code Playgroud)

  • 如果直接复制,请注意第一行末尾的换行符 (6认同)
  • 不错的别名。但是最后缺少 ' ' (2 个单引号字符)。即使没有它它也能工作,但是......如果你想在最后添加更多命令,你会看到文字不完整。所以它应该是```alias lst='ls -R | grep ":$" | sed -e '"'"'s/:$//'"'"' -e '"'"'s/[^-][^\/]*\//--/g'"'"' -e '"'"'s/^/ /'"'"' -e '"'"'s/-/|/'"'"''``` (3认同)

Fra*_*eau 11

最好的答案当然是tree。但是,为了改进依赖 grep 输出的其他答案ls -R,这里有一个 shell 脚本,它使用 awk 打印子目录树。首先,输出示例:

\n
\n.\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 匹配\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 围兜\n \xe2\ x94\x9c\xe2\x94\x80\xe2\x94\x80 数据\n \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 源\n \xe2\x94\ x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 html\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 数据\n \xe2\x94\x82 \ xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 绘图\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 方法\n \xe2\x94\x82 \xe2\ x94\x9c\xe2\x94\x80\xe2\x94\x80 信息\n \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 软\n \xe2\x94\ x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 imgs\n \xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94 \x80 ascii\n \xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 符号\n \xe2\x94\x82 \xe2\x94\x94 \xe2\x94\x80\xe2\x94\x80 js\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 毫秒\n
\n

然后,代码:

\n
ls -qLR 2>/dev/null \\\n| grep '^./' \\\n| sed -e 's,:$,,' \\\n| awk '\n    function tip(new) { stem = substr(stem, 1, length(stem) - 4) new }\n    {\n        path[NR] = $0\n    }\n    END {\n        elbow = "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 "; pipe = "\xe2\x94\x82   "; tee = "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 "; blank = "    "\n        none = ""\n        #\n        # Model each stem on the previous one, going bottom up.\n        for (row = NR; row > 0; row--) {\n            #\n            # gsub: count (and clean) all slash-ending components; hence,\n            # reduce path to its last component.\n            growth = gsub(/[^/]+\\//, "", path[row]) - slashes\n            if (growth == 0) {\n                tip(tee)\n            }\n            else if (growth > 0) {\n                if (stem) tip(pipe) # if...: stem is empty at first!\n                for (d = 1; d < growth; d++) stem = stem blank\n                stem = stem elbow\n            }\n            else {\n                tip(none)\n                below = substr(stem, length(stem) - 4, 4)\n                if (below == blank) tip(elbow); else tip(tee)\n            }\n            path[row] = stem path[row]\n            slashes += growth\n        }\n        root = "."; print root\n        for (row = 1; row <= NR; row++) print path[row]\n    }\n'\n
Run Code Online (Sandbox Code Playgroud)\n

该代码提供了比其他解决方案更好看的结果,因为在子目录树中,任何分支中的装饰都取决于其下面的分支。因此,我们需要ls -R以相反的顺序处理输出,从最后一行到第一行。

\n


msa*_*msa 10

由于我对其他(非tree)答案的输出不太满意(请参阅我在 Hassou 的答案中的评论),因此我尝试更多地模仿trees 的输出。

它类似于罗伯特的答案,但水平线并非都从开头开始,而是从应该开始的地方开始。只好用perl,虽然,但在我的情况下,系统在这里我就不对treeperl是可用的。

ls -aR | grep ":$" | perl -pe 's/:$//;s/[^-][^\/]*\//    /g;s/^    (\S)/??? \1/;s/(^    |    (?= ))/?   /g;s/    (\S)/??? \1/'
Run Code Online (Sandbox Code Playgroud)

输出(缩短):

.
??? fd
??? net
?   ??? dev_snmp6
?   ??? nfsfs
?   ??? rpc
?   ?   ??? auth.unix.ip
?   ??? stat
?   ??? vlan
??? ns
??? task
?   ??? 1310
?   ?   ??? net
?   ?   ?   ??? dev_snmp6
?   ?   ?   ??? rpc
?   ?   ?   ?   ??? auth.unix.gid
?   ?   ?   ?   ??? auth.unix.ip
?   ?   ?   ??? stat
?   ?   ?   ??? vlan
?   ?   ??? ns
Run Code Online (Sandbox Code Playgroud)

欢迎提出避免多余垂直线的建议:-)

我仍然非常喜欢在 Hassou 回答的评论中的解决方案,没有(不完全正确的)线条,它会更干净。对于我的用例,我还删除了全局缩进并添加了ls隐藏文件的选项,如下所示:

ls -aR | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//  /g'
Run Code Online (Sandbox Code Playgroud)

输出(更短):

.
  fd
  net
    dev_snmp6
    nfsfs
    rpc
      auth.unix.ip
    stat
    vlan
  ns
Run Code Online (Sandbox Code Playgroud)


Rob*_*ert 6

我正在美化@Hassou 的答案的输出:

ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//??/g' -e 's/?/?/' -e '$s/?/?/'
Run Code Online (Sandbox Code Playgroud)

这很像tree现在的输出:

.
??pkcs11
??pki
????ca-trust
??????extracted
????????java
????????openssl
????????pem
??????source
????????anchors
??profile.d
??ssh
Run Code Online (Sandbox Code Playgroud)

您还可以为其创建别名:

.
??pkcs11
??pki
????ca-trust
??????extracted
????????java
????????openssl
????????pem
??????source
????????anchors
??profile.d
??ssh
Run Code Online (Sandbox Code Playgroud)

顺便说一句,tree在某些环境中不可用,例如 MinGW。所以替代是有帮助的。

  • @LeosLiterak:在 Windows 上,本机“tree”应该可以通过命令提示符(“cmd”)或 PowerShell 来使用:-) (2认同)

Raj*_*mal 5

在 bashrc 中添加以下函数可以让您运行不带任何参数的命令,该命令显示当前目录结构,并且当使用任何路径作为参数运行时,将显示该路径的目录结构。这避免了在运行命令之前切换到特定目录的需要。

function tree() {
    find ${1:-.} | sed -e "s/[^-][^\/]*\//  |/g" -e "s/|\([^ ]\)/|-\1/"
}
Run Code Online (Sandbox Code Playgroud)

这也适用于 gitbash。

来源:@javasheriff 的评论(此处)