2013-07-18 61 views
0

我寫了一個基本腳本來測試遞歸輸出對目錄或文件系統的選擇最大目錄和重複,然後整齊地輸出結果。有沒有辦法將一個數組和一些if/then語句組合起來,使其更加優雅,並繼續遞歸,直到沒有更多的目錄匹配,然後從數組中打印輸出?用du定義數組行走目錄

#!/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] 
+0

看看:http://fsv.sourceforge.net/;在debian上:apt-get install fsv –

回答

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 
+0

謝謝,我也會看看測試這個 –

+0

這停在第一級,只是看起來在/不管第一個參數是多少 –

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,請用簡單的sort替換gsort。 (需要-h - 排序結果du -h

+0

謝謝,我會看看這個,不幸的是我支持的系統沒有新的排序-h選項。我希望他們做 –

+0

$ UNAME - SR Linux的2.6.18-348.3.1.el5 $排序-h 排序:無效選項 -^h 嘗試'排序--help」以獲取更多信息 –

+0

@gNU!。很奇怪 - 也許是在package'coreutils'中。nvm - 它可以是簡單的y修改 - 只需使用'du -k'和'sort -nr' - 並將需要的結果轉換爲「人類可讀格式」... – jm666