tac
é mais fácil de entender no caso em que foi projetado principalmente, que é quando o separador é um terminador de registro, ou seja, o separador aparece após o último registro. Imprime os registros (incluindo cada terminador) na ordem inversa.
$ echo -n fooabara | tac -s a; echo
rabafooa
A entrada consiste em três registros ( foo
, b
e r
), cada um seguido pelo separador a
; a saída consiste em três registros ( r
, b
e foo
), cada um seguido pelo separador a
.
Se o último registro não terminar com um terminador de registro, ele ainda será impresso primeiro, sem nenhum separador de registro.
$ echo -n fooabar | tac -s a; echo
rbafooa
O último registro r
acaba sendo concatenado com o penúltimo registro b
sem separador entre eles, já que não havia separador no final do último registro.
Sua entrada parece um pouco mais confusa por causa das novas linhas. Vamos ver com vírgulas em vez de novas linhas:
$ echo -n a,b,c,b,a, | tac -s a; echo
,,b,c,b,aa
Existem três registros de entrada: um vazio (com um terminador a
), o volumoso ,,b,c,b,
(novamente com um terminador) e um ,
não finalizado no final. Esses registros (cada um com seu terminador, exceto o último registro que não tem um terminador) são impressos na ordem inversa.
Sua confusão provavelmente vem de esperar que o "separador" seja um separador - mas isso é um equívoco: é realmente um terminador de registro. --before
faz dele um iniciador.