0

我编写了一个基本脚本来测试针对目录或文件系统的递归 du 输出,该目录或文件系统选择最大的目录并重复,然后整齐地输出结果。有没有一种方法可以将数组和一些 if/then 语句结合起来,使其更加优雅并继续递归,直到没有更多目录匹配,然后打印数组的输出?

#!/bin/bash

dir1=$1
du1=$(du -x --max-depth=1 $dir1 | sort -nr | awk '{ print $2 }' | \
    xargs du -hx --max-depth=0 | egrep -v "sys|proc|boot|lost|media|mnt|selinux" | head -10 | tail -n +2)

dir2=$(echo "$du1"|head -1|awk '{print $2}')
du2=$(du -x --max-depth=1 $dir2 | sort -nr | awk '{ print $2 }' | \
    xargs du -hx --max-depth=0 | egrep -v "sys|proc|boot|lost|media|mnt|selinux" | head -10 | tail -n +2)

dir3=$(echo "$du2"|head -1|awk '{print $2}')
du3=$(du -x --max-depth=1 $dir3 | sort -nr | awk '{ print $2 }' | \
    xargs du -hx --max-depth=0 | egrep -v "sys|proc|boot|lost|media|mnt|selinux" | head -10 | tail -n +2)

dir4=$(echo "$du3"|head -1|awk '{print $2}')
du4=$(du -x --max-depth=1 $dir4 | sort -nr | awk '{ print $2 }' | \
    xargs du -hx --max-depth=0 | egrep -v "sys|proc|boot|lost|media|mnt|selinux" | head -10 | tail -n +2)

dir5=$(echo "$du4"|head -1|awk '{print $2}')
du5=$(du -x --max-depth=1 $dir5 | sort -nr | awk '{ print $2 }' | \
    xargs du -hx --max-depth=0 | egrep -v "sys|proc|boot|lost|media|mnt|selinux" | head -10 | tail -n +2)

dir6=$(echo "$du5"|head -1|awk '{print $2}')
du6=$(du -x --max-depth=1 $dir6 | sort -nr | awk '{ print $2 }' | \
    xargs du -hx --max-depth=0 | egrep -v "sys|proc|boot|lost|media|mnt|selinux" | head -10 | tail -n +2)

echo -e "##LEVEL1##"
paste -d ' ' <(echo "$du1") <(echo "$(file $(echo "$du1" | \
    awk '{print $2}')|cut -d' ' -f2- | sed -e 's/[a-zA-Z0-9]/[&/' -e 's/$/]/')")
echo -e "##LEVEL2##"
paste -d ' ' <(echo "$du2") <(echo "$(file $(echo "$du2" | \
    awk '{print $2}')|cut -d' ' -f2- | sed -e 's/[a-zA-Z0-9]/[&/' -e 's/$/]/')")
echo -e "##LEVEL3##"
paste -d ' ' <(echo "$du3") <(echo "$(file $(echo "$du3" | \
    awk '{print $2}')|cut -d' ' -f2- | sed -e 's/[a-zA-Z0-9]/[&/' -e 's/$/]/')")
echo -e "##LEVEL4##"
paste -d ' ' <(echo "$du4") <(echo "$(file $(echo "$du4" | \    
    awk '{print $2}')|cut -d' ' -f2- | sed -e 's/[a-zA-Z0-9]/[&/' -e 's/$/]/')")
echo -e "##LEVEL5##"
paste -d ' ' <(echo "$du5") <(echo "$(file $(echo "$du5" | \
    awk '{print $2}')|cut -d' ' -f2- | sed -e 's/[a-zA-Z0-9]/[&/' -e 's/$/]/')")
echo -e "##LEVEL6##"
paste -d ' ' <(echo "$du6") <(echo "$(file $(echo "$du6" | \
    awk '{print $2}')|cut -d' ' -f2- | sed -e 's/[a-zA-Z0-9]/[&/' -e 's/$/]/')")

这是一个示例输出:

#./rdu.sh / 2>/dev/null
##LEVEL1##
12G     /opt  [directory]
1.9G    /usr  [directory]
452M    /var  [directory]
352M    /root [directory]
179M    /home [directory]
116M    /lib  [directory]
46M     /tmp  [sticky directory]
28M     /sbin [directory]
21M     /etc  [directory]
##LEVEL2##
8.5G    /opt/zenoss [directory]
2.9G    /opt/zends  [directory]
##LEVEL3##
6.6G    /opt/zenoss/perf     [directory]
510M    /opt/zenoss/ZenPacks [directory]
486M    /opt/zenoss/var      [directory]
461M    /opt/zenoss/lib      [directory]
250M    /opt/zenoss/log      [directory]
85M     /opt/zenoss/Products [directory]
49M     /opt/zenoss/packs    [directory]
31M     /opt/zenoss/share    [directory]
26M     /opt/zenoss/webapps  [directory]
##LEVEL4##
6.5G    /opt/zenoss/perf/Devices [directory]
59M     /opt/zenoss/perf/Daemons [directory]
##LEVEL5##
289M    /opt/zenoss/perf/Devices/10.0.4.218                    [directory]
288M    /opt/zenoss/perf/Devices/10.215.68.9                   [directory]
287M    /opt/zenoss/perf/Devices/10.0.4.18                     [directory]
161M    /opt/zenoss/perf/Devices/<removed>                     [directory]
145M    /opt/zenoss/perf/Devices/10.219.68.12                  [directory]
143M    /opt/zenoss/perf/Devices/VMs--                         [directory]
143M    /opt/zenoss/perf/Devices/10.0.4.219                    [directory]
143M    /opt/zenoss/perf/Devices/10.0.4.19                     [directory]
136M    /opt/zenoss/perf/Devices/10.215.68.8                   [directory]
##LEVEL6##
279M    /opt/zenoss/perf/Devices/10.0.4.218/ltmvirtualservers [directory]
7.1M    /opt/zenoss/perf/Devices/10.0.4.218/os                [directory]
888K    /opt/zenoss/perf/Devices/10.0.4.218/hw                [directory]
840K    /opt/zenoss/perf/Devices/10.0.4.218/loadbalancerports [directory]
4

2 回答 2

1

你的代码在我的系统上不起作用,所以我无法测试它。但是你可以这样做:

function durec {
    dir1=$1
    level=$2
    du1=$(du -x --max-depth=1 $dir1 | sort -nr | awk '{ print $2 }' | \
        xargs du -hx --max-depth=0 | egrep -v "sys|proc|boot|lost|media|mnt|selinux" | head -10 | tail -n +2)
    echo -e "##LEVEL$level##"
    paste -d ' ' <(echo "$du1") <(echo "$(file $(echo "$du1" | \
        awk '{print $2}')|cut -d' ' -f2- | sed -e 's/[a-zA-Z0-9]/[&/' -e 's/$/]/')")
    let level++
    dir2=$(echo "$du1"|head -1|awk '{print $2}')
    if [ ! -z "$dir" ]; then
        durec $dir2 $level
    fi  
}

# call the function
durec / 1
于 2013-07-18T05:32:17.643 回答
0

您的第一个du计算整个文件系统。在您一次又一次地计算每个子目录之后。

这对我来说似乎是一些不必要的计数(阅读废话),因为您可以保存第一个输出du并仅在其上工作......

就像是:

root="${1:-.}"
count=${2:-10}
tmp1=/tmp/durec_du.$$
tmp2=/tmp/durec_tmp.$$
trap "rm -f $tmp1 $tmp2;exit" 0 1 2 3 15

#human readable format - need GNU sort    
#du -h "$root" | gsort -hr > $tmp1

#KB format
du -k "$root" | sort -nr > $tmp1
cp /dev/null $tmp2

level=0
durec() {
    dir=$1
    biggest=$(grep "    ${dir}/[^/][^/]*$" $tmp1 | tee $tmp2 | head -1 | sed 's/^[0-9BKMGTP][0-9BKMGTP]*    //')
    #               ^^^ ----------------------- one <TAB> character ---------------------------------- ^^^^ 
    # if you have GNU version of sed, and grep replace the <TAB> with \t                     
    [[ -n "$biggest" ]] || return
    let level++
    echo "##LEVEL$level##"
    head -$count $tmp2
    durec "$biggest"
}

durec "$root"

命令gsort是. GNU sort如果您的标准sort是 GNU,请将 替换gsort为简单的sort. (需要-hdu -h.

于 2013-07-19T07:33:08.880 回答