Here’s the awk solution you wanted.
(Well, gawk [GNU awk], to be specific; this won’t work in POSIX awk.)
awk '
function dump() {
PROCINFO["sorted_in"] = "@ind_str_asc"
for (arg3 in group) {
PROCINFO["sorted_in"] = "@ind_num_asc"
for (line_num in group[arg3]) {
print group[arg3][line_num]
}
PROCINFO["sorted_in"] = "@ind_str_asc"
}
}
{
if ($1 != saved_arg1) {
dump()
delete group
saved_arg1 = $1
}
group[$3][NR] = $0
}
END {
dump()
}
'
The main work begins in the middle.
For each line, if its $1 value is different
from the most recent one we’ve seen,
that means that we’re entering a new group.
Dump the data from the previous group (i.e., write it to the output),
delete the saved data for the previous group,
and then remember the new $1 value.
Then, in either case, add the current line to the group array.
This is a two-dimensional array, indexed by $3 value and NR
(line number).
So, for example, for the first six lines of your sample input, we get
group["A"][1] = "1 bob A"
group["B"][2] = "1 jim B"
group["A"][3] = "1 Kate A"
group["C"][4] = "1 Nancy C"
group["A"][5] = "1 bill A"
group["A"][6] = "1 Jason A"
When we see $1 = 2 on line 7,
we call the dump function (defined at the top of the program).
for (arg3 in group) sets arg3 to A, B and C, in that order.
Then, for arg3 = A, the loop for (line_num in group[arg3])
(i.e., for (line_num in group["A"]) sets line_num
to 1, 3, 5 and 6, in that order.
And so we print out
1 bob A
1 Kate A
1 bill A
1 Jason A
And so on for the other $3 values.
And so on for the other $1 values.
$1=1are together (consecutive) in the input file, and then all the lines with$1=2are together, and then all the lines with$1=3are together, … and then all the lines with$1=42are together, … and finally all the lines with$1=2000are together? And you want the output to have the same property? (2) Please confirm what I wrote about the$2values.