歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網

代碼解釋

日期:2017/2/27 9:48:10   编辑:更多Linux
  #!/sbin/ksh dir=${1:-.} (cd $dir;pwd) find $dir -type d -print du awk '{print $2, "== ("$1/2"kb)"}' sort -f sed -e "s,[^ /]*/([^ /]*) ==,--1," -e"s,[^ /]*/, ,g" #The End 感覺有些難度,不知哪位大俠能夠給在下解釋一下! 第五行是緊跟在第四行之後的,由於太長被強制換行了。 這個程序包含的知識點比較多,如果不是在這些點方面均有了解的話,理解起來會比較困難。但是仔細分析搞懂,還是很有收獲的。因此在這裡細細解讀一下: 程序目的: 對指定的目錄,顯示該目錄及其下所有子目錄所占用的空間。顯示方式上,要求以類windows樹狀結構的方式表現目錄和子目錄的關系,顯示空間大小用(?kb)的樣式說明。 程序代碼: (1)#!/sbin/ksh (2)dir=${1:-.} (3)(cd $dir;pwd) (4)find $dir -type d -print du awk '{print $2, "== ("$1/2"kb)"}' sort -f sed -e "s,[^ /]*/([^ /]*) ==,--1," -e"s,[^ /]*/, ,g" (1)表明使用的shell解釋器為ksh (2)對變量dir賦值,如果執行該程序時指定了第一參數$1,那麼dir的值即為$1(即指定目錄),如果沒有指定參數,那麼dir的值為"."(即當前目錄)。這種變量設置的模式還有=value、+value、:?value、?value、:=value、:-value,各有其功能。 (3)為了首先顯示一下處理的路徑所在的主目錄,需要進至該目錄,然後用pwd命令顯示出來。用()括起來,表示這兩句作為一組命令一起執行,而且有個重要的好處就是執行完後不會影響程序的當前路徑,可以理解是()使其內部命令在一子shell中運行,一旦執行完畢便恢復原shell的環境。 (4)這句是關鍵。 首先find $dir -type d -print表明要把$dir指定的目錄下所有的子目錄都找到並顯示出來。-type d說明找的是目錄而不是文件。 然後,使用du命令顯示每一目錄所占空間由於du命令顯示的單位是512字節塊,因此要將得到的值除以2,得到kb值。根據du的輸出結果,第二列是目錄,第一列是值,因此使用awk分別處理,$1/2的表達式要用引號引起是要讓awk正確識別表達式。 sort -f是要把輸出的結果排序,按字母順序排序,便於使用的人察看。使用-f可以讓sh排序時對大小寫不敏感。 sed一句是關鍵中的關鍵,-e的寫法可以使sed連續執行多套命令,此處有兩個-e。來看命令集:s打頭,表明了是一個替換任務,跟我們熟悉的不同,我們平時用s/aa/bb/這樣的形式較多,但對於sed來說,分隔符是可以自行任意指定的,這裡sed將跟在s命令後的","作為了分隔符。於是就有了s,...,...,的樣子。 我們知道格式是“s/源串/目標串/”,那麼第一組命令,源串是說什麼呢?[]的用法在sed中表示:取[]字符組中的一個字符,而[]中的第一位若是"^",則表示不取後面的任何一個字符。那麼[^ /]*/就表示匹配這樣的格式:"由不是空格或/的一個或多個字符組成的串,後面緊跟一個/",接下來有(......)的格式,這種格式用在源串中,表示用這種符號括注的部分要sed記住,而且sed會給這個部分自動起個名字叫1,如果在源串中還有這樣的標記,就依次命名為2,3......。這1要sed記住什麼呢?是"[^ /]*",這還是說"由不是空格或/的一個或多個字符組成的串"。1之後還有" =="也是源串中要求匹配的。再來看目標串,就是要替換成的串,是"--1",作者認為""是特殊字符,所以前跟號(其實不必)。"--"是普通符號了,1就是我們剛才在源串中要求標記的部分,換到這裡來。 第二組命令簡單一些。源串:"[^ /]*/",仍然是"由不是空格或/的一個或多個字符組成的串,後面緊跟一個/",目標串是" ",最後一個g表明全行替換,就是說如果在一行中有多處匹配源串,都要替換成目標串。 再從該程序應用的角度看這一句的功能: 作者是要把這樣的顯示結果 . == (904724kb) ./bak == (1kb) ./billfile == (1kb) ./bin == (11646kb) ./bin../misc == (16kb) .................... 替換成這樣的結果 . == (904724kb) --bak (1kb) --billfile (1kb) --bin (11646kb) --images (16kb) .................... 對於"aaa/xxxx/yyyy =="分解這一要求,實際是兩步,先把"xxxx/yyyy =="替換為"--yyyy",然後將aaa變成" "(如沒有aaa則無行為),在aaa中含有幾個/,就換成幾個" "。這裡的sed命令恰好完成了這一功能。 程序改進: (1)實際該程序沒有使用ksh的任何特殊功能,改為sh仍可正常運行,兼容性會更好。 (2)先find再du是沒有必要的。因為du本身就能尋找子目錄,且自動顯示每個子目錄的大小。另外,如果對指定的目錄無讀權限的話,find就會報出錯,但直接用du則沒事。 (3)""在sed中不是特殊字符不必再用""轉義了。 最後我的建議結果如下: #!/bin/sh dir=${1:-.} (cd $dir;pwd) du $dir awk '{print $2, "== ("$1/2"kb)"}' sort -fsed -e "s,[^ /]*/([^ /]*) ==,--1," -e "s,[^ /]*/, ,g" michaelds 解釋的太好了。 我想我們大家在注意shell的時候,應該注意shell中處處用得到的正則表達式。 ^,$,.,*,[] 應該很清楚,這樣在sed ,awk,case,vi ...裡都能順暢自如.




Copyright © Linux教程網 All Rights Reserved