Digamos que tengo este archivo, que no contiene nada más que
a
b
c
b
a
Usando tac --separator=a file
BASH [en un Linux basado en Debian], obtengo esto:
# empty line
# empty line
b
c
b
aacommand@prompt # two a just before the prompt
Pregunta: Hasta donde tengo entendido, --separator=a
define que a
marca la ruptura dentro de la cadena, en lugar de newline
.¿Es esto correcto?
Probé esto con otras cadenas y mucha más entrada y terminé con un gran desastre. Supongo que todas las otras opciones funcionan bastante bien: si las uso, tac --before
primero obtengo alrededor de cinco líneas vacías, pero esto es lo que debería suceder, ¿verdad?
Respuesta1
tac
es más fácil de entender en el caso para el que está diseñado principalmente, que es cuando el separador es un terminador de registro, es decir, el separador aparece después del último registro. Imprime los registros (incluido cada terminador) en orden inverso.
$ echo -n fooabara | tac -s a; echo
rabafooa
La entrada consta de tres registros ( foo
, b
y r
), cada uno seguido por el separador a
; la salida consta de tres registros ( r
, b
y foo
), cada uno seguido por el separador a
.
Si el último registro no termina con un terminador de registro, aún así se imprime primero, sin separador de registros.
$ echo -n fooabar | tac -s a; echo
rbafooa
El último registro r
termina concatenado con el penúltimo registro b
sin separador intermedio, ya que no había ningún separador al final del último registro.
Su entrada parece un poco más confusa debido a las nuevas líneas. Veámoslo con comas en lugar de nuevas líneas:
$ echo -n a,b,c,b,a, | tac -s a; echo
,,b,c,b,aa
Hay tres registros de entrada: uno vacío (con un terminador a
), uno voluminoso ,,b,c,b,
(de nuevo con un terminador) y uno sin terminar ,
al final. Estos registros (cada uno con su terminador, excepto el último registro que no tiene terminador) se imprimen en orden inverso.
Su confusión probablemente proviene de esperar que el “separador” sea un separador, pero ese es un nombre inapropiado: en realidad es un terminador de registro. --before
lo convierte en un iniciador.
Respuesta2
El siguiente ejemplo podría ayudar a utilizar la --regex
opción:
$ 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
En este ejemplo, el archivo records
contiene registros de varias líneas, cada uno de los cuales comienza con una línea ( ^...$
) que comienza con ---
, seguida de un número ( [0-9]+
) y una secuencia opcional de signos menos ( -*
). Se puede ver el orden de las líneas en cada registro y se conserva su línea de encabezado.
Utilizo tac
esta forma para mostrar las entradas de los archivos de registro en orden inverso, como se usa en aplicaciones de feeds como Twitter. Por ejemplo, para imprimir sólo los dos últimos registros en orden inverso:
tac --before --regex --separator=^---[0-9]+-*$ example \
| awk '/^---[0-9]+-*$/ {c++} c>2 {exit}{print}'