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 osBH
eTR
como separadores de registros (o padrão é\n
ewline). -
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 lernext
record. - 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'