Via awk and the GNU-feature (!) of defining array traversal. Note: stores the whole file in RAM once, but you said "over 100 volumes" so I assume the file is not incredibly large.
The idea is
- separate records by empty lines (two newlines in a row, no TAB assumed)
- use parentheses as field separators: get lines into array with volume number as index identifier. Therefore the number needs to be separated out with
sub - sort output by "volume X" index
- simply replace the numbers (293G etc) for each entry in a sorted manner
Script:
BEGIN { RS=ORS="\n\n"RS="" ; ORS="\n\n" ; FS="[()]" }
{id=$2 ; sub(/volume /,"",id) ; vol[id]=$0}
END {PROCINFO["sorted_in"]="@ind_num_asc"
n=293n=292
for ( id in vol ) { gsub(/^\t.../,"\t"n++,vol[id]) ; print vol[id] } }
Run via
awk -f script inputfile