Sorting pairs of lines based on a single field in one of those lines
Transform your data into an easily-sorted format, then sort it back. So:
to_one_line_per_record() { local inf_line= line= while read -r line; do if [[ $line = "#"* ]]; then inf_line=$line else printf '%s\n' "${inf_line},$line" fi done}from_one_line_per_record() { local inf_f1 inf_f2 url while IFS=, read -r inf_f1 inf_f2 url; do printf '%s,%s\n%s\n' "$inf_f1" "$inf_f2" "$url" done}to_one_line_from_record | sort -t, -k2,2 | from_one_line_per_record
With your given input, the output of to_one_line_per_record
is:
#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBC,http://AnotherStreamUrl.m3u8#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HD,http://StreamUrl.m3u8#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discovery,http://DisStreamUrl.m3u8
Passing that through sort -t, -k2,2
, the output becomes:
#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HD,http://StreamUrl.m3u8#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discovery,http://DisStreamUrl.m3u8#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBC,http://AnotherStreamUrl.m3u8
And passing that through from_one_line_per_record
, it transforms out to:
#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HDhttp://StreamUrl.m3u8#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discoveryhttp://DisStreamUrl.m3u8#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBChttp://AnotherStreamUrl.m3u8
Here is one using GNU awk's asort
:
$ awk 'BEGIN { FS="," } # define , as field separator{ p=( NR%2 ? $2 : p ) # every other record updates p a[p]=a[p] (a[p]==""?"":ORS) $0 # second record in pair is appended to} # first ORS separatedEND { n=asort(a,b,"@ind_str_asc") # sort on key for(i=1;i<=n;i++) # loop them print b[i] # and output}' file#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HDhttp://StreamUrl.m3u8#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discoveryhttp://DisStreamUrl.m3u8#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBChttp://AnotherStreamUrl.m3u8
It supports only unique keys in Is groups records with equal $2
$2
but does not order within that group, for example:
$ awk '{...}' file file#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HDhttp://StreamUrl.m3u8#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HDhttp://StreamUrl.m3u8#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discoveryhttp://DisStreamUrl.m3u8#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discoveryhttp://DisStreamUrl.m3u8#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBChttp://AnotherStreamUrl.m3u8#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBChttp://AnotherStreamUrl.m3u8
Similar in structure to the answer from @Charles, but uses small awk
scripts instead of the bash functions.
Save the following in its own file, named (for example) sortem.sh:
#!/usr/bin/env bashset -e[[ $# -ge 1 ]] && exec < "$1"awk -F , '/^#EXTINF/ {s=$0} /^http/ {print s FS $0}' | \ sort -t , -k 2,2 | \ awk -F , '{print $1 FS $2 "\n" $3}'
Make the file executable via:
$ chmod +x sortem.sh
Identify the file where the input to be processed is saved. For example, you might save it in a file named sortem_input.txt
. Using cat
to display this file's contents shows:
$ cat sortem_input.txt#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBChttp://AnotherStreamUrl.m3u8#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HDhttp://StreamUrl.m3u8#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discoveryhttp://DisStreamUrl.m3u8
Process this input using an invocation like:
$ ./sortem.sh sortem_input.txt
...or:
$ ./sortem.sh < sortem_input.txt
...or more generally:
$ <commands that generate input> | ./sortem.sh
The output looks like:
#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HDhttp://StreamUrl.m3u8#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discoveryhttp://DisStreamUrl.m3u8#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBChttp://AnotherStreamUrl.m3u8