是否有任何linux命令,我可以从Bash脚本调用,将以树的形式打印目录结构,例如,
folder1
a.txt
b.txt
folder2
folder3
是否有任何linux命令,我可以从Bash脚本调用,将以树的形式打印目录结构,例如,
folder1
a.txt
b.txt
folder2
folder3
当前回答
最好的答案当然是树。但是,为了改进依赖于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的输出,从最后一行到第一行。
其他回答
在bashrc中添加下面的函数可以让您在不带任何参数的情况下运行该命令,该命令显示当前目录结构,当以任何路径作为参数运行时,将显示该路径的目录结构。这样可以避免在运行命令之前切换到特定目录。
function tree() {
find ${1:-.} | sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/"
}
这在gitbash中也适用。
来源:@javasheriff的评论
由于我对其他(非树)答案的输出不太满意(参见我在Hassou's answer的评论),我试着更多地模拟树的输出。
这与罗伯特的答案相似,但水平线并不都是从起点开始的,而是从应该开始的地方开始的。虽然不得不使用perl,但在我的情况下,在我没有树的系统上,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
将已有的答案组合并扩展为t壳函数
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
:
|更可以放在函数的末尾,方便使用。
将Hassou的解决方案添加到你的.bashrc,尝试:
alias lst='ls -R | grep ":$" | sed -e '"'"'s/:$//'"'"' -e '"'"'s/[^-][^\/]*\//--/g'"'"' -e '"'"'s/^/ /'"'"' -e '"'"'s/-/|/'"'"
由于这是一个成功的评论,我添加它作为一个答案: 要以树的形式打印目录结构, 与文件
find . | sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/"