命令“du -h”,但当当前目录大于阈值时继续

命令“du -h”,但当当前目录大于阈值时继续

我正在寻找类似的东西

du -h /var/log/ --max-depth=2 --threshold=5G

但为了du如果空间高于该阈值,则在当前目录上再次执行。有没有办法在不重复原始输出的情况下保持顺序?

例如,对于 5Gb 的阈值:

10.3G /lib/
8.9G /lib/lib1
2.1G /lib/lib1/files1
6.3G /lib/lib1/files2
3.2G /lib/lib1/files2/foz
1.3G /lib/lib2
8.3G /tmp/
8.2G /tmp/foo
5.2G /tmp/foo/bar
5.1G /tmp/foo/bar/bar1
900M /tmp/foo/bar/bar2
1.0G /tmp/foo/bat
1.0G /tmp/foo/baz

最初尝试该命令时,我没有得到所需的输出。 for 循环或将 du 命令放入函数中会有帮助吗?提前致谢

答案1

它不是du可以直接交付的东西,但一点点递归 shell 脚本可以充分包装它,以给出您想要的近似值。

首先,将所有这些放入一个文件中,例如/usr/local/bin/rdu并使其可执行:

#!/bin/bash
shopt -s dotglob

# Pretty printer
du_pp() {
    local value=$1 unitIndex=0 units="KMGTP"

    while [ $value -ge 1024 ]
    do
        ((unitIndex++)); value=$((value/1024))
    done
    echo "$value${units:$unitIndex:1}"
}

# Convert to K
du_ck() {
    local value=$1 l=${#1} unit

    ((l--))
    unit=${value:$l:1}
    [[ 'KMGTP' == *"$unit"* ]] && value=${value:0:$l} || unit='K'

    until [ "$unit" = 'K' ]
    do
        case "$unit" in
            M)  value=$((value*1024)) unit='K';;
            G)  value=$((value*1024)) unit='M';;
            T)  value=$((value*1024)) unit='G';;
            P)  value=$((value*1024)) unit='T';;
        esac
    done
    echo $value
}

# Call du, recursively expanding nodes greater than the threshold
du_rx() {
    local threshold=$1
    shift
    local starts=("$@")

    du -ks "${starts[@]}" |
        while IFS=$'\t' read -r size dir
        do
            printf '%s\t%s\n' "$(du_pp "$size")" "$dir"
            if [ -d "$dir" ] && [ $size -ge $threshold ]
            then
                [ "$dir" == '/' ] && dir=
                du_rx "$threshold" "$dir"/*
            fi
        done
}

# Call du_rx 1024000 /var
threshold=$(du_ck $1)
shift
starts=("$@")

du_rx $threshold "${starts[@]}"

至少使用两个参数调用它:以K(默认)、MGT表示的阈值大小P,以及一个或多个起始目录。例如,

rdu 1000 /var/log    # threshold is 1000 KiB
rdu 1G /var /usr     # threshold is 1 GiB

这是它的工作原理。

有两个支持功能du_ppdu_ck。第一个将 KiB 中的值转换为“人类可读”的等价值,可以使用 MiB、GiB、TiB 或 PiB 单位。第二个将字符串转换为4G等效的 KiB 值。两者都不稳定,但在大多数情况下都应该有效。

驱动函数是递归的du_rx。这会遍历起始目录中的条目并调用du -s它们来获取摘要大小。如果摘要大小超过阈值,则(自行)调用该函数,并将当前项目作为新的起始目录。

至于du所有条目都是输出,而不仅仅是目录。您可以通过包装此块来避免这种情况:

printf '%s\t%s\n' "$(du_pp "$size")" "$dir"
if [ -d "$dir" ] && [ $size -gt $(du_ck "$threshold") ]
then
    [ "$dir" == '/' ] && dir=
    du_rx "$threshold" "$dir"/*
fi

像这样

if [ -d "$dir" ] 
then
    printf '%s\t%s\n' "$(du_pp "$size")" "$dir"
    if [ $size -gt $(du_ck "$threshold") ]
    then
        [ "$dir" == '/' ] && dir=
        du_rx "$threshold" "$dir"/*
    fi
fi

相关内容