2011-08-05 78 views
2

問題:BASH:用瘋狂的名字對文件進行排序

需要在對函數進行操作之前對數組進行排序。

首先,陣列中裝入文件:

unset a i 
counter=1 
while IFS= read -r -d $'\0' file; do 
    a[i++]="$file" 
done < <(find $DIR -type f -print0) 

接着,陣列的每個成員被髮送到起作用

for f in "${a[@]}" 
do 
    func_hash "$f" 
    [ $(expr $counter % 20) -eq 0 ] && printf "=" 
    counter=$((counter + 1)) 
done 

不知何故一種需要被扔進上述for循環。通過排序陣列上的SO帖看過 ,但不知何故,當我嘗試在排序上時,我的瘋狂文件名 會引起問題。

想法?

謝謝!

Bubnoff

UPDATE:這裏的代碼排序:

while IFS= read -r -d $'\0' file; do 
    func_hash "$file" 
    [ $(expr $counter % 20) -eq 0 ] && printf "=" 
    counter=$((counter + 1)) 
done < <(find $DIR -type f -print0 | sort -z +1 -1) 

它是由完整的路徑,而不是文件名排序。任何想法如何 文件名排序給定的路徑是功能所需?

更新2:決定妥協。

我的主要目標是避免使用排序的臨時文件。 GNU排序可以寫回原來的 文件與它的「-o」選項,所以現在我可以:

sort -o $OUT -t',' -k 1 $OUT 

任何人有更多的「優雅」的解決方案(知道是什麼意思)。

解決以下見jw013的答案。謝啦!

+1

更換與呼叫行外部命令expr我們需要的文件名和所需的排序順序(例子,捕捉了幾個經常和所有不尋常的情況下)。祝你好運。 – shellter

+1

你也沒有鏈接到你嘗試過的SO帖子。我的第一個直覺就是將'find'輸出傳遞給'<()'內的'sort',這對那些時髦的文件不起作用嗎? – nhed

+0

nhed - 不,它沒有。我會再試一次併發布錯誤。 – Bubnoff

回答

2

編輯

while IFS= read -r -d/ && read -r -d '' file; do 
    a[i++]="$file" 
done < <(find "$DIR" -type f -printf '%f/%p\0' | sort -z -t/ -k1) 

理由:

  • 我作一個假設,/從來都不是一個文件名中的合法字符(這似乎在大多數* nix的文件系統合理的,因爲它是路徑分隔符)。
  • -printf用於打印的文件名,不領先的目錄,然後用路徑則完整的文件名,由/分離。排序發生在由/分開的第一個字段上,它應該是沒有路徑的完整文件名。
  • read被修改爲第一次使用/作爲分隔符拋出了無路的文件名。

側面說明

任何POSIX外殼應支持模運算作爲其算術擴展的一部分。您可以在第二循環中與

[ $((counter % 20)) -eq 0 ] ... 
+0

的種類。看到我上面的更新。查找返回完整路徑並按完整路徑對「排序」進行排序。我需要在循環中保留完整路徑的同時按文件名進行排序,以便將完整路徑傳遞給函數。 – Bubnoff

+0

看看我的新編輯,看它是否有效。 – jw013

+0

完全輝煌!完美的作品。儘管它比單獨的「排序」要慢很多。謝謝! – Bubnoff