文章目录
使用ls实现tree
实现思路
-
使用ls -F 打印文件类型,如果是目录后面跟/,如果是可执行文件后面跟*;
-
使用grep -v /$ 筛选文件排除目录,-v为反向筛选;
-
使用grep /$ 仅筛选目录;
-
${files[@]} 是获取数组的全部元素;
-
获取文件直接打印,获取目录后,打印目录,拼接父目录给当前目录(因为shell执行总是在当前目录,如果只传目录,会报错找不到目录),然后递归打印。
代码如下:#!/bin/bash
将shell默认的三种分隔符中的空格分隔符剔除,解决文件名有空格情况下的问题
IFS=$'\t\n'
函数:递归地打印目录内容
print_tree() {
local indent=$1
local dir=2 local files=((ls -F dir | grep -v /))
local dirs=($(ls -F dir | grep /))
# 打印当前目录的文件
for file in "{files[@]}"; do echo "{indent}{file}" done # 递归打印目录 for subdir in "{dirs[@]}"; do
echo "{indent}{subdir}"
subdir="{dir}/{subdir}"
print_tree "|......${indent}" ${subdir}
done
}从当前目录开始打印树状图
print_tree "" "."
测试一下,输出如下:
a/
|......b/
|......|......c/
|......|......d/
|......|......f/
|......c/
|......|......f/
|......|......|......test*
|......|......|......tt.txt
当然这种方法虽然简单,但是文件是可执行文件,那么在文件名后会跟一个*,风格不统一,下面再介绍一种打印方式。
使用find实现tree
实现思路:
find 命令加参数-type f 可以仅查找文件排除掉目录,但是查出来的文件带父目录,maxdepth可以指定查找深度,1表示只在本层目录中查找;
basename 命令可以删除指定结尾的后缀,也能打印除了/的最后一部分字符。比如basename /usr/local/Centos输出结果为Centos,但是如果目录名有空格就不会得到预期的效果;
tr 命令可以替换字符,比如可以将目录名中的空格替换为/,使得basename可以得到预期效果;
代码如下:
#!/bin/bash
IFS=$'\t\n'
# 函数:递归地打印目录内容
print_tree() {
local indent=$1
local dir=$2
local files=($(find $dir -maxdepth 1 -type f ))
local dirs=($(find $dir -maxdepth 1 -type d))
if [ "${#dirs[@]}" -gt "0" ];then
unset dirs[0]
fi
# 打印当前目录的文件
for file in "${files[@]}"; do
echo "${indent}$(basename $(echo $file | tr ' ' '\'))"
done
# 递归打印目录
for subdir in "${dirs[@]}"; do
echo "${indent}$(basename $(echo $subdir | tr ' ' '\ '))"
print_tree "|......${indent}" ${subdir}
done
}
# 从当前目录开始打印树状图
print_tree "" "."
测试一下,输出如下:
a
|......c
|......|......f
|......|......|......test
|......|......|......tt.txt
|......b
|......|......f
|......|......c
|......|......d
快一起试试吧~