2012-06-22 111 views
7

我有一個文件結構,看起來像這樣如何在每個目錄中查找文件名最大的文件?

./501.res/1.bin 
./503.res/1.bin 
./503.res/2.bin 
./504.res/1.bin 

,我想找到的文件路徑.bin文件中的每個具有最高號作爲文件名的目錄。所以我要尋找的輸出將

./501.res/1.bin 
./503.res/2.bin 
./504.res/1.bin 

一個文件可以有最高的數字是9。

問題

我該怎麼做,在BASH?

我已經儘量來作爲find .|grep bin|sort

回答

1

什麼使用awk?你可以得到第一次出現真正簡單:

[[email protected] ~]$ cat data1 
./501.res/1.bin 
./503.res/1.bin 
./503.res/2.bin 
./504.res/1.bin 
[[email protected] ~]$ awk 'BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1' data1 
./501.res/1.bin 
./503.res/1.bin 
./504.res/1.bin 
[[email protected] ~]$ 

要通過一對夫婦的種種拿到最後出現你可以管:

[[email protected] ~]$ sort -r data1 | awk 'BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1' | sort 
./501.res/1.bin 
./503.res/2.bin 
./504.res/1.bin 
[[email protected] ~]$ 

假設您正在使用「查找」和「grep的」 ,你可以這樣做:

find . -name \*.bin -type f -print | sort -r | awk 'BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1' | sort 

這是如何工作的?

find命令有許多有用的選項,包括通過水珠來選擇你的文件,選擇文件類型的能力,等等​​。它的輸出你已經知道了,並且成爲輸入sort -r

首先,我們對輸入數據進行反向排序(sort -r)。這確保了在任何目錄內,編號最高的文件將首先顯示。那個結果被傳入awk。 FS是字段分隔符,它使得$2變成諸如「/ 501」,「/ 502」等等的東西。awk腳本具有condition {action}形式的部分,它們針對每一行輸入進行評估。如果缺少某個條件,則該操作會在每一行中運行。如果條件爲「1」並且沒有任何操作,則打印該行。所以,這個腳本被分解如下:

  • a[$2] {next} - 如果陣列a下標$ 2(即「/ 501」)存在,就直接跳到下一行。否則...
  • {a[$2]=1} - 設置數組下標$ 2:1,因此,在今後的首要條件將評估爲真,那麼...
  • 1 - 打印線。

這個awk腳本的輸出將是你想要的數據,但是以相反的順序。最後的sort按照您期望的順序重新排列。

現在......這是很多管道,當你要求它在同一時間處理數百萬行輸入時,排序可能有點資源飢渴。這個解決方案對於少量的文件是完全足夠的,但是如果你處理的是大量的輸入,請告訴我們,我可以想出一個一體化的awk解決方案(這需要超過60秒來寫)。

UPDATE

每丹尼斯的明智的建議,我上面包括在AWK腳本可以通過改變它從

BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1 

雖然這是功能相同的改進,以

BEGIN{FS="."} $2 in a {next} {a[$2]} 1 

,其優點是您只需定義數組成員而不是將值分配給它們,這可以節省內存或cpu de待你實施awk。無論如何,它更乾淨。

+0

最好使用'{next}'中的$ 2來測試數組中元素的存在。這樣做不會簡單地通過引用它們來創建新的數組元素。這是我前幾天討論這件事時想說的話。順便說一句,如果你這樣使用'in',你可以做'{a [$ 2]}'而不是'{a [$ 2] = 1'',但是兩者都可以。 –

+0

@丹尼斯威廉姆森,啊,現在我明白你在前些天得到了什麼。非常感謝指針。 :) – ghoti

0

我想出了這樣的成才:

for dir in $(find . -mindepth 1 -type d | sort); do 
    file=$(ls "$dir" | sort | tail -n 1); 
    [ -n "$file" ] && (echo "$dir/$file"); 
done 

也許可以更簡單

+0

我想你應該有某種-n的編號可能變爲高於9 – bcelary

+0

@bcelary - *規定的任擇議定書「的最高數量可以文件有9。「* – ghoti

+0

啊 - 對不起。無法注意:) – bcelary

2

測試:

find . -type d -name '*.res' | while read dir; do 
    find "$dir" -maxdepth 1 | sort -n | tail -n 1 
done 
+1

它不顯示路徑。 – jcubic

+0

修正了它。 find ... -maxdepth 1現在正確顯示路徑。謝謝。 – bcelary

0

如果發現內調用一個shell就是一個選擇嘗試這種

find * -type d -exec sh -c "echo -n './'; ls -1 {}/*.bin | sort -n -r | head -n 1" \; 
3

水珠,保證詞法順序進行擴展。

for dir in ./*/ 
do 
    files=($dir/*)   # create an array 
    echo "${files[@]: -1}" # access its last member 
done 
0

這裏是一個班輪

find . -mindepth 1 -type d | sort | sed -e "s/.*/ls & | sort | tail -n 1 | xargs -I{} echo &\/{}/" | bash 
相關問題