Digamos que eu tenha este arquivo, contendo nada além de
a
b
c
b
a
Usando tac --separator=a file
no BASH [em um Linux baseado em Debian], recebo o seguinte:
# empty line
# empty line
b
c
b
aacommand@prompt # two a just before the prompt
Pergunta: Pelo que entendi, --separator=a
define que a
marca a quebra dentro da string, ao invés de newline
.Isto está certo?
Eu tentei isso com outras strings e muito mais entradas e acabei com uma bagunça. Todas as outras opções funcionam bem, presumo: se eu usar, tac --before
primeiro recebo cerca de cinco linhas vazias, mas isso é o que deveria acontecer, certo?
Responder1
tac
é mais fácil de entender no caso para o qual 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 separador de registros.
$ echo -n fooabar | tac -s a; echo
rbafooa
O último registro r
acaba concatenado com o penúltimo registro b
sem nenhum separador entre eles, pois não havia separador no final do último registro.
Sua entrada parece um pouco mais confusa por causa das novas linhas. Vamos ver isso 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
), um 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 possui terminador) são impressos na ordem inversa.
Sua confusão provavelmente vem de esperar que o “separador” seja um separador – mas isso é um nome impróprio: é realmente um terminador de registro. --before
em vez disso, torna-o um iniciador.
Responder2
O exemplo a seguir pode ajudar a usar a --regex
opção:
$ cat records
---1---
1
2
3
---2
A
B
C
---3--
a
b
c
$ tac --before --regex --separator=^---[0-9]+-*$ records
---3--
a
b
c
---2
A
B
C
---1---
1
2
3
Neste exemplo, o arquivo records
contém registros multilinhas, cada um iniciado com uma linha ( ^...$
) que começa com ---
, seguida por um número ( [0-9]+
) e uma sequência opcional de sinais de menos ( -*
). Pode-se ver a ordem das linhas em cada registro e sua linha de cabeçalho são preservadas.
Eu uso tac
essa forma para mostrar as entradas dos arquivos de log na ordem inversa, conforme usado em aplicativos de feed como o Twitter. Por exemplo, para imprimir apenas os dois últimos registros em ordem inversa:
tac --before --regex --separator=^---[0-9]+-*$ example \
| awk '/^---[0-9]+-*$/ {c++} c>2 {exit}{print}'