在mac环境下使用shell脚本实现tree命令

文章目录

使用ls实现tree

实现思路

  1. 使用ls -F 打印文件类型,如果是目录后面跟/,如果是可执行文件后面跟*;

  2. 使用grep -v /$ 筛选文件排除目录,-v为反向筛选;

  3. 使用grep /$ 仅筛选目录;

  4. ${files@} 是获取数组的全部元素;

  5. 获取文件直接打印,获取目录后,打印目录,拼接父目录给当前目录(因为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

快一起试试吧~

相关推荐
counterxing17 小时前
最近发现一个 Mac 工具,有点像把 Raycast、语音输入法、截图和录屏塞到了一起
macos·ai编程·claude
戴为沐1 天前
Linux内存扩容指南
linux
zylyehuo1 天前
Linux 彻底且安全地删除文件
linux
用户805533698032 天前
主线 U-Boot 上 RK3506:和闭源 rkbin 拔河的三个隐性契约
linux·嵌入式
用户034095297912 天前
linux fcitx 5 雾凇拼音 设置在中文输入法下仍然输入英文标点
linux
Web3探索者4 天前
可视化服务器管理和传统命令行区别是什么?新手教程:Linux 运维到底该用图形界面还是 SSH 命令行?
linux·ssh
zylyehuo4 天前
Linux系统中网线与USB网络共享冲突
linux
Sokach10155 天前
Linux Shell 脚本从零到能用:一个新手的一天学习总结
linux
AlfredZhao6 天前
Docker 容器时区不对,`timedatectl` 不存在怎么办?
linux·timezone
zzzzzz3107 天前
9K Star 炸裂开源!这个 C 语言写的代码知识图谱,把 Linux 内核索引压缩到了 3 分钟
linux·服务器·sql