使用du定义行走目录的数组

时间:2013-07-18 04:57:40

标签: arrays linux bash sed awk

我编写了一个基本脚本来测试针对选择最大目录并重复的目录或文件系统的递归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]

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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。 (需要-h - 对du -h的结果进行排序。