Isso deve funcionar e classificar cada bloco com base em # em BH|# como linha de cabeçalho de bloco e em% ascendenteBH|100, BH|102 , BH|105 , ... order.
awk -v RS='BH|TR' 'NR>1{ seen[NR]=$0; next } { printf $0 }
END{ TR="TR"seen[NR]; delete seen[NR]; asort(seen);
for(x in seen) printf "BH"seen[x]; printf TR }' infile
HR|testing file
BH|100
B2|cat|10
B2|dog|20
BT|4
BH|102
B2|fan|10
B2|bulb|20
B2|washer|10
B2|dryer|10
BT|6
BH|105
B2|apple|10
B2|banana|20
B2|melon|10
BT|5
TR|17
-
Este
RS='BH|TR'define osBHeTRcomo separadores de registros (o padrão é\newline). -
Este bloco
NR>1{ seen[NR]=$0; next }será executado para todos os ecords R , mas primeiro (NRé N umber de R ecord ); assim, para cada Número de Registro como a chave (Índice) de um array associado chamado visto , o valor de todo o registro será definido para ele e depois lernextrecord. - Se não for o primeiro registro, então
{ printf $0 }. Isso será executado apenas uma vez, porque da próxima vezNR>1.
No final, o bloco END{ ... } será executado e será executado:
- Este
TR="TR"seen[NR]copiando o último registro da matriz inserida em uma variável chamada TR e, em seguida, excluí-lo da matrizdelete seen[NR]. - Esse
asort(seen)classifica a matriz vista com base em seus valores salvos; então - Fazemos o loop de
for(x in seen)sobre essa matriz eprintf "BH"seen[x] - No final, imprimimos o TR .
Se você não se importa com a primeira e a última linha do seu arquivo, você também pode:
sed '1d; $d' infile |awk '{printf $0(/^BT/?"\n":"#")}' |sort |tr '#' '\n'