La opción del comando tac crea un resultado extraño

La opción del comando tac crea un resultado extraño

Digamos que tengo este archivo, que no contiene nada más que

a
b
c
b
a

Usando tac --separator=a fileBASH [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=adefine que amarca 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 --beforeprimero obtengo alrededor de cinco líneas vacías, pero esto es lo que debería suceder, ¿verdad?

Respuesta1

taces 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, by r), cada uno seguido por el separador a; la salida consta de tres registros ( r, by 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 rtermina concatenado con el penúltimo registro bsin 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. --beforelo convierte en un iniciador.

Respuesta2

El siguiente ejemplo podría ayudar a utilizar la --regexopció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 recordscontiene 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 tacesta 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}'

información relacionada