【问题标题】:Tree hierarchy in BashBash 中的树层次结构
【发布时间】:2019-11-24 14:19:57
【问题描述】:

我正在尝试在 bash 中实现一个函数,该函数显示给定深度的文件/目录树。它需要 3 个参数。

$1 = *current directory*
$2 = *current depth*
$3 = *lines*

例如,如果我的当前目录是“.../living/”,我的深度是2,我的函数应该输出:

DIR .../living/
----DIR animals
--------FILE dog
--------FILE cat
----DIR plants
--------FILE flowers

如您所见,每更改一次深度,行数就会增加 4 行。文件的类型(DIR,FILE)不是这个线程的问题。 到目前为止,这是我所拥有的:

function tree {
    #some code to get the directory in variable cwd
    ...
    a=$(getType $cwd)
    echo "$a $cwd"
    depth=3 #the value does not matter, it's just for you guys to see
    drawTree $cwd $depth "----"
}

function drawTree {
    if [[ $2 == 0 ]]; then
         return
    fi

    dat=$1
    list=$(ls $dat)
    depth=$2
    lines=$3

    for d in $list; do
        f="$dat/$d"
        t=$(getType $f)
        echo "$lines$t $d"
        if [[ $t == "DIR" ]]; then
            g=$(($depth-1))
            l="$lines----"
            if [[ $g > 00 ]]; then
                drawTree $f $g $l
            fi
        fi
    done

这段代码的输出很遗憾是错误的,我不知道为什么。

【问题讨论】:

标签: bash recursion tree


【解决方案1】:

该代码存在很多问题。

最严重的是你的变量不是本地的(参见help local),这在递归函数中可能是灾难性的。在drawtree 的循环中,第二次迭代将看到对$depth$lines 的不必要修改,这两种情况都会导致输出以不同的方式不正确。

还有:

g=$(($depth-1))
l="$lines----"
if [[ $g > 00 ]]; then
    drawTree $f $g $l
fi

最好不要写太多不必要的变量,使用算术而不是字符串比较:

if (( depth > 1 )); then
   drawTree $f $((depth - 1)) ${lines}----
fi

最后:

list=$(ls $dat)
for d in $list; do

如果文件路径中存在空格或 shell 元字符,将导致灾难性的失败。更好的是使用 bash 数组和 glob 扩展而不是 ls 命令):

# Create an array from a glob 
list=("$dat"/*)
# Use the elements of the array, individually quoted:
for d in "${list[@]}"; do

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    • 2015-12-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2013-01-31
    相关资源
    最近更新 更多