簡體   English   中英

Linux 命令以樹的形式打印目錄結構

[英]Linux command to print directory structure in the form of a tree

是否有我可以從 Bash 腳本調用的任何 linux 命令,該腳本將以樹的形式打印目錄結構,例如,

folder1
   a.txt
   b.txt
folder2
   folder3

這就是你要找的嗎? 它應該在大多數發行版中(可能作為可選安裝)。

~> 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

示例取自維護者的網頁。

您可以添加選項-L # ,其中#由數字替換,以指定最大遞歸深度。

刪除-d以顯示文件。

你可以使用這個:

ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'

它將在幾秒鍾內顯示當前沒有文件的子目錄的圖形表示,例如在/var/cache/中:

   .
   |-apache2
   |---mod_cache_disk
   |-apparmor
   |-apt
   |---archives
   |-----partial
   |-apt-xapian-index
   |---index.1
   |-dbconfig-common
   |---backups
   |-debconf

資源

此命令用於顯示文件夾和文件

find . | sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/"

示例輸出:

.
 |-trace.pcap
 |-parent
 | |-chdir1
 | | |-file1.txt
 | |-chdir2
 | | |-file2.txt
 | | |-file3.sh
 |-tmp
 | |-json-c-0.11-4.el7_0.x86_64.rpm

資料來源:來自@javasheriff 評論。 它作為評論被淹沒並將其作為答案發布可以幫助用戶輕松發現它。

由於這是一個成功的評論,我將其添加為答案:
要以樹的形式打印目錄結構,
帶文件

 find . | sed -e "s/[^-][^\/]*\//  |/g" -e "s/|\([^ ]\)/|-\1/" 

要將 Hassou 的解決方案添加到 your.bashrc,請嘗試:

alias lst='ls -R | grep ":$" | sed -e '"'"'s/:$//'"'"' -e '"'"'s/[^-][^\/]*\//--/g'"'"' -e '"'"'s/^/   /'"'"' -e '"'"'s/-/|/'"'"

由於我對其他(非tree )答案的輸出不太滿意(請參閱我在 Hassou 的回答中的評論),我嘗試更多地模仿tree的輸出。

這與羅伯特的回答相似,但水平線並非都從頭開始,而是從應該開始的地方開始。 雖然不得不使用perl ,但就我而言,在我沒有tree的系統上, perl是可用的。

ls -aR | grep ":$" | perl -pe 's/:$//;s/[^-][^\/]*\//    /g;s/^    (\S)/└── \1/;s/(^    |    (?= ))/│   /g;s/    (\S)/└── \1/'

輸出(縮短):

.
└── 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

歡迎提出避免多余垂直線的建議:-)

我仍然非常喜歡Ben 在 Hassou 的回答評論中的解決方案,沒有(不完全正確的)線條,它更清晰。 對於我的用例,我還刪除了全局縮進並添加了ls隱藏文件的選項,如下所示:

ls -aR | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//  /g'

輸出(更短):

.
  fd
  net
    dev_snmp6
    nfsfs
    rpc
      auth.unix.ip
    stat
    vlan
  ns

我正在美化@Hassou 的回答輸出:

ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//──/g' -e 's/─/├/' -e '$s/├/└/'

這很像tree現在的輸出:

.
├─pkcs11
├─pki
├───ca-trust
├─────extracted
├───────java
├───────openssl
├───────pem
├─────source
├───────anchors
├─profile.d
└─ssh

你也可以為它取一個別名:

alias ltree=$'ls -R | grep ":$" | sed -e \'s/:$//\' -e \'s/[^-][^\/]*\//──/g\' -e \'s/─/├/\' -e \'$s/├/└/\''

順便說一句, tree在某些環境中不可用,比如 MinGW。 所以備用是有幫助的。

在 bashrc 中添加以下函數可以讓您在不帶任何參數的情況下運行命令,顯示當前目錄結構,並且在以任何路徑作為參數運行時,將顯示該路徑的目錄結構。 這避免了在運行命令之前切換到特定目錄的需要。

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

這也適用於 gitbash。

資料來源:@javasheriff 的評論在這里

最好的答案當然是樹。 但是,為了改進依賴於ls -R輸出的其他答案,這里有一個 shell 腳本,它使用 awk 打印子目錄樹。 首先,輸出示例:

.
└── matching
    ├── bib
    ├── data
    │   └── source
    │       └── html
    ├── data
    │   └── plots
    ├── method
    │   ├── info
    │   └── soft
    │       ├── imgs
    │       │   ├── ascii
    │       │   └── symbol
    │       └── js
    └── ms

然后,代碼:

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

該代碼給出了比其他解決方案更好看的結果,因為在子目錄樹中,任何分支中的裝飾都依賴於它下面的分支。 因此,我們需要以相反的順序處理ls -R的輸出,從最后一行到第一行。

您還可以結合使用 find 和 awk 命令來打印目錄樹。 詳見《 如何使用linux find和awk組合命令打印多級樹目錄結構

find . -type d | awk -F'/' '{ 
depth=3;
offset=2;
str="|  ";
path="";
if(NF >= 2 && NF < depth + offset) {
    while(offset < NF) {
        path = path "|  ";
        offset ++;
    }
    print path "|-- "$NF;
}}'

將現有答案組合並擴展為t shell function

t() {
  find -E "${1:-.}" -maxdepth "${2:-3}" \
    -not -regex ".*\/((.idea|.git|.venv|node_modules|venv)\/.*|.DS_Store)" \
  | sort | sed \
    -e "s/[^-][^\/]*\// ├ /g" \
    -e "s/├ \//├ /g" \
    -e "s/├  ├/│  ├/g" \
    -e "s/├  ├/│  ├/g" \
    -e "s/├  │/│  │/g" \
    -e '$s/├/└/'
}

適用於 Mac:

$ t
.
 ├ src
 │  ├ .idea
 │  ├ plugins
 │  │  ├ .flake8
 │  │  ├ .git
 │  │  ├ .github
 │  │  ├ .gitignore
 │  │  ├ .pre-commit-config.yaml
 │  │  ├ .python-version
 │  │  ├ Makefile
 │  │  ├ README.md
 │  │  ├ buildspecs
 │  │  ├ cicd
 │  │  ├ cicd.py
 │  │  ├ docker
 │  │  ├ packages
 │  │  ├ plugin_template
 │  │  ├ plugins
 │  │  ├ scripts
 │  │  └ venv


$ t . 2
.
 ├ src
 │  ├ .idea
 │  └ plugins


$ t src/plugins/ | more
 │  ├
 │  ├ .flake8
 │  ├ .git
 │  ├ .github
 │  │  ├ pull_request_template.md
 │  ├ .gitignore
 │  ├ .pre-commit-config.yaml
 │  ├ .python-version
 │  ├ Makefile
 │  ├ README.md
 │  ├ buildspecs
 │  │  ├ test-and-deploy.yml
 │  ├ cicd
:

| more 為方便起見,可以將| more放在 function 的末尾。

是否可以使用遞歸但將其限制為3個級別?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM