BASH: Sort array of files with crazy names
Problem:
Need to sort array before operating on them with function.
First, array is loaded with files:
unset a i
counter=1
while IFS= read -r -d $'\0' file; do
a[i++]="$file"
done < <(find $DIR -type f -print0)
Next, each member of array is sent to function
for f in "${a[@]}"
do
func_hash "$f"
[ $(expr $counter % 20) -eq 0 ] && printf "="
counter=$((counter + 1))
done
Somehow a sort needs to be thrown into the above for loop. Have looked through the SO posts on sorting arrays but somehow my crazy file names cause issues when I try to tack on a sort.
Ideas?
Thanks!
Bubnoff
UPDATE: Here's code with sort:
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)
It's sorting by full path rather than file name. Any ideas on how to sort by file name given that the path is needed for the function?
UPDATE 2: Decided to compromise.
My main goal was to avoid temp files using sort. GNU sort can write back to the original file with its '-o' option so now I can:
sort -o $OUT -t',' -k 1 $OUT
Anyone have a more 'elegant' solution ( whatever that means ).
SOLVED See jw013's answer below. 开发者_开发问答Thanks man!
EDIT
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 )
Rationale:
- I make the assumption that
/
is never a legal character within a file name (which seems reasonable on most *nix filesystems since it is the path separator). - The
-printf
is used to print the file name without leading directories, then then full file name with path, separated by/
. The sort takes place on the first field separated by/
which should be the full file name without path. - The
read
is modified to first use/
as a delimiter to throw out the pathless file name.
side note
Any POSIX shell should support the modulo operator as part of its arithmetic expansion. You can replace line with the call to external command expr
in the second loop with
[ $(( counter % 20 )) -eq 0 ] ...
精彩评论