How to bash sort files numerically correctly in awk? (Solved)

For discussions about programming, and for programming questions and advice


Moderator: Forum moderators

Post Reply
blumenwesen
Posts: 37
Joined: Sun Apr 10, 2022 10:02 pm

How to bash sort files numerically correctly in awk? (Solved)

Post by blumenwesen »

Hello, have tried with awk not sort, because further processing has to be done to arrange files numerically correctly.
Please help.

musica 1 00
musica 5 00
musica 10 00
musicb 2 00
musicb 18 00
...

Code: Select all

ar0="musica 10 00.mp3\nmusica 10 01.mp3\nmusica 8 00.mp3\nmusica 8 01.mp3\nmusicb 11 00.mp3\nmusicb 11 01.mp3\nmusicb 2 00.mp3\nmusicb 2 01.mp3\nmusicb 5 00.mp3\nmusicb 5 01.mp3"

# complete script 1 wrong order
echo -e "$ar0" | awk -v y=-1 -v x=-1 '{match($0, /([ 0-9]+[.][m][p][3])/, w); $2=substr(w[1], 2, RLENGTH-5); $1=substr($0, 1, length($0)-(length($2)+8)); 
# split numbers /↑\
if($1==c){y++} else{y=0; x++}; a[x,y]=$1; b[x,y]=$2} {c=$1}
# sort array different names /↑\
END{for(v=0; v<=x; v++){for(u=0; u<=y; u++){d[b[v,u]]=a[v,u]}; 
# merge array /↑\
PROCINFO["sorted_in"]="@val_num_desc"; for(t in d){print d[t]"-"t; delete d[t]}}}
# sort output /↑\'

# complete script 2 wrong order
echo -e "$ar0" | awk -v y=-1 '{match($0, /([ 0-9]+[.][m][p][3])/, w); $2=substr(w[1], 2, RLENGTH-5); $1=substr($0, 1, length($0)-(length($2)+8)); 
if(a!=$1){y++}; b[y,$2]=$1} {a=$1} 
END{PROCINFO["sorted_in"]="@val_num_desc"; for(x in b){split(x, c, SUBSEP); print b[c[1],c[2]]" "c[2] } }'

# error because different array length
echo -e "a 1\na 5\na 10\na 0\nb 0\nb 10\nb 5" | awk '{PROCINFO["sorted_in"]="@val_num_desc"; 
if(a!="" && a!=$1){for(z in b){print b[z]"-"z }; a=""}; b[$2]=$1} {a=$1} 
ENDFILE{for(z in b){print b[z]"-"z}}'[\CODE]
User avatar
Flash
Moderator
Posts: 972
Joined: Tue Dec 03, 2019 3:13 pm
Location: Arizona, U.S.
Has thanked: 50 times
Been thanked: 124 times

Re: How to bash sort files numerically correctly in awk?

Post by Flash »

So the way you show them is how you want them to look after they're sorted by a script?

Chaos coordinator :?
blumenwesen
Posts: 37
Joined: Sun Apr 10, 2022 10:02 pm

Re: How to bash sort files numerically correctly in awk?

Post by blumenwesen »

In the logical order, not the one given by the system.
correct: 1,2,3,4,5,6,7,8,9,10,11,12,...
wrong: 1,10,11,12,13,14,15,16,18,19,2,20,...

User avatar
Flash
Moderator
Posts: 972
Joined: Tue Dec 03, 2019 3:13 pm
Location: Arizona, U.S.
Has thanked: 50 times
Been thanked: 124 times

Re: How to bash sort files numerically correctly in awk?

Post by Flash »

The best way I found to do that is to add leading zeros: 01, 02, 03....10, 11, 12....etc. If there are more than 99 items, you have to add two leading zeros to the single digits and one leading zero to the double digits: 001, 002, .... 010, 020, etc. It might be possible for a script to do that. To start with, it would need to find the maximum digits in the list. In other words, if the largest number in the list is a 4-digit number, then it would add 3 leading zeros to the single-digit numbers in the list; 2 leading zeros to the 2-digit numbers and one leading zero to the 3-digit numbers in the list.

Chaos coordinator :?
User avatar
MochiMoppel
Posts: 1222
Joined: Mon Jun 15, 2020 6:25 am
Location: Japan
Has thanked: 20 times
Been thanked: 435 times

Re: How to bash sort files numerically correctly in awk?

Post by MochiMoppel »

Code: Select all

ar0="musica 10 00.mp3\nmusica 10 01.mp3\nmusica 8 00.mp3\nmusica 8 01.mp3\nmusicb 11 00.mp3\nmusicb 11 01.mp3\nmusicb 2 00.mp3\nmusicb 2 01.mp3\nmusicb 5 00.mp3\nmusicb 5 01.mp3"

# complete script 2 , used to be wrong order
echo -e "$ar0" | awk -v y=-1 '{match($0, /([ 0-9]+[.][m][p][3])/, w); $2=substr(w[1], 2, RLENGTH-5); $1=substr($0, 1, length($0)-(length($2)+8)); 
if(a!=$1){y++}; b[y,$2]=$1} {a=$1} 
END{PROCINFO["sorted_in"]="@val_num_desc"; for(x in b){split(x, c, SUBSEP); print b[c[1],c[2]]" "c[2] } }'| sort -k 1,1 -k 2,2h -k3,3h

I have no idea what the awk stuff is supposed to do. In your example it seems to serve no purpose (apart from looking cool). Could be completely left out:

Code: Select all

ar0="musica 10 00.mp3\nmusica 10 01.mp3\nmusica 8 00.mp3\nmusica 8 01.mp3\nmusicb 11 00.mp3\nmusicb 11 01.mp3\nmusicb 2 00.mp3\nmusicb 2 01.mp3\nmusicb 5 00.mp3\nmusicb 5 01.mp3"
echo -e "${ar0//.mp3}" | sort -k 1,1 -k 2,2h -k3,3h

Both scripts result in
musica 8 00
musica 8 01
musica 10 00
musica 10 01
musicb 2 00
musicb 2 01
musicb 5 00
musicb 5 01
musicb 11 00
musicb 11 01

User avatar
Flash
Moderator
Posts: 972
Joined: Tue Dec 03, 2019 3:13 pm
Location: Arizona, U.S.
Has thanked: 50 times
Been thanked: 124 times

Re: How to bash sort files numerically correctly in awk?

Post by Flash »

Just to add to what I said about leading zeros, here's something I found while poking around in Pcdripper by Plinej:
(Line 1780)

Code: Select all

		##add a zero before single digit track numbers
		if [ "`echo $TRACKS | wc -c | sed 's/ //g'`" = 2 ]; then
			NUM=0"$TRACKS"
		else
			NUM=$TRACKS
		fi

Since CDs can have no more than 99 tracks, there was no need for more than one leading zero.

Chaos coordinator :?
User avatar
MochiMoppel
Posts: 1222
Joined: Mon Jun 15, 2020 6:25 am
Location: Japan
Has thanked: 20 times
Been thanked: 435 times

Re: How to bash sort files numerically correctly in awk?

Post by MochiMoppel »

Flash wrote: Sun Jul 16, 2023 1:28 am

Just to add to what I said about leading zeros, here's something I found while poking around in Pcdripper by Plinej

Code: Select all

if [ "`echo $TRACKS | wc -c | sed 's/ //g'`" = 2 ]; then
	NUM=0"$TRACKS"
else
	NUM=$TRACKS
fi

Could be done with a single command:

Code: Select all

printf -v NUM %02i $TRACKS

Since it requires no subshell and no external tools like wc and sed it would be more efficient and faster (and shorter :) )

User avatar
Flash
Moderator
Posts: 972
Joined: Tue Dec 03, 2019 3:13 pm
Location: Arizona, U.S.
Has thanked: 50 times
Been thanked: 124 times

Re: How to bash sort files numerically correctly in awk?

Post by Flash »

Thanks. I'll substitute that for what I posted and see how it works.

Chaos coordinator :?
blumenwesen
Posts: 37
Joined: Sun Apr 10, 2022 10:02 pm

Re: How to bash sort files numerically correctly in awk?

Post by blumenwesen »

I have to edit the file names in the script, so I used awk.
Thanks for the help, now it clicked =).

Code: Select all

ar0="musica 10 00.mp3\nmusica 10 01.mp3\nmusica 8 00.mp3\nmusica 8 01.mp3\nmusicb 11 00.mp3\nmusicb 11 01.mp3\nmusicb 2 00.mp3\nmusicb 2 01.mp3\nmusicb 5 00.mp3\nmusicb 5 01.mp3"

time echo -e "${ar0//.mp3}" | sort -k 1,1 -k 2,2h -k3,3h

#real	0m0,009s
#user	0m0,002s
#sys	0m0,006s

time echo -e "$ar0" | awk -v y=-1 '{match($0, /([ 0-9]+[.][m][p][3])/, w); $2=substr(w[1], 2, RLENGTH-5); $1=substr($0, 1, length($0)-(length($2)+8)); if(length($2)==4){$2="0"$2}; a[$2]=$1} ENDFILE{PROCINFO["sorted_in"]="@val_num_desc"; for(z in a){if(substr(z, 1, length(z)-4)=="0"){print a[z]" "substr(z, 2, length(z))} else{print a[z]" "z}}}'

#real	0m0,008s
#user	0m0,000s
#sys	0m0,008s
Post Reply

Return to “Programming”