如何在bash/shell脚本中实现树命令?

wqnecbli  于 2023-02-05  发布在  Shell
关注(0)|答案(2)|浏览(168)

我尝试在bash中实现一些代码,其输出类似于终端中的"tree"命令。
这就是:

listContent() {
    local file
    for file in "$1"/*; do
        if [ -d $file ]; then
            countSpaces $file
            echo $?"Directory: $file"
            listContent "$file"
        elif [ -f $file ]; then
            countSpaces $file
            echo $?"File: $file"
        fi
    done
}

countSpaces() {
    local space="   "
    for (( i=0; i<${#$1}; i++ )); do
        if [ ${file:$i:1} = "/" ]; then
        space = space + space
        return space
    done
}

listContent "$1"

运行我给出的脚本:./www.example.com directoryName,其中scriptName是我的脚本,directoryName是参数,它是代码应该从中启动的目录的名称。scriptName.sh directoryName where scriptName is my script and directoryName is the argument which is the name of the directory from which the code should start.
我希望看到这样的输出:

Directory: Bash/Test1Dir
    File: Bash/Test1Dir/Test1Doc.txt
Directory: Bash/Test2Dir
    Directory: Bash/Test2Dir/InsideTest2DirDir
        File: Bash/Test2Dir/insideTest2DirDoc.txt
File: Bash/test.sh

但是我在完成这段代码时遇到了一些麻烦。有人能帮我弄清楚为什么它不工作,我应该做些什么改变吗?
会很感激的。

wn9m85ua

wn9m85ua1#

正确而有效的实现可能如下所示:

listContent() {
  local dir=${1:-.} whitespacePrefix=$2 file
  for file in "$dir"/*; do
    [ -e "$file" ] || [ -L "$file" ] || continue
    if [ -d "$file" ]; then
      printf '%sDirectory %q\n' "$whitespacePrefix" "${file##*/}"
      listContent "$file" "${whitespacePrefix}    "
    else
      printf '%sFile %q\n' "$whitespacePrefix" "${file##*/}"
    fi
  done
}

注:

  • 我们使用调用栈来跟踪空格的数量,而不是计算空格,并附加到每个递归调用中,这样就避免了计算每个名称中/的数量。
  • 我们引用 * 所有 * 参数展开,除了在有限的上下文中隐式避免了字符串分裂和全局展开。
  • 我们避免尝试将$?用于跟踪数字退出状态这一预期目的之外的任何其他用途。
  • 只要存在不受控制的数据(如文件名),我们就使用printf %q,以确保即使是恶意名称(包含换行符、光标控制字符等)也能明确地打印出来。
py49o6xq

py49o6xq2#

如果您想要一个没有DirectoryFile前导的可视化表示,那么下面是一个简单的一行程序( Package 在shell函数中)。

treef() (
    [ -d "$1" ] && { dir="$1"; shift; } || dir='.'
    find "$dir" "$@" | sed -e 's@/@|@g;s/^\.|//;s/[^|][^|]*|/ |/g;/^[. |]*$/d'
)

相关问题