Imprimir la última columna de una línea en un archivo

135

Tengo un archivo que se escribe / actualiza constantemente. Quiero encontrar la última línea que contenga una palabra en particular, luego imprimir la última columna de esa línea.

El archivo se parece a esto. Se agregarán más líneas A1 / B1 / C1 a lo largo del tiempo.

A1 123 456
B1 234 567
C1 345 678
A1 098 766
B1 987 6545
C1 876 5434

Traté de usar

tail -f file | grep A1 | awk '{print $NF}'

para imprimir el valor 766, pero no se emite nada.

¿Hay alguna forma de hacer esto?

Rayne
fuente

Respuestas:

199

No ves nada, debido al almacenamiento en búfer. Se muestra la salida, cuando hay suficientes líneas o se alcanza el final del archivo. tail -fsignifica esperar más entradas, pero no hay más líneas filey la tubería grepnunca se cierra.

Si omite -fde tailla salida se muestra inmediatamente:

tail file | grep A1 | awk '{print $NF}'

@EdMorton tiene razón, por supuesto. Awk también puede buscar A1, lo que acorta la línea de comando para

tail file | awk '/A1/ {print $NF}'

o sin cola, mostrando la última columna de todas las líneas que contienen A1

awk '/A1/ {print $NF}' file

Gracias al comentario de @ MitchellTracy, tailpodría perder el registro que contiene A1y, por lo tanto, no obtendrá ningún resultado. Esto se puede resolver cambiando taily awkbuscando primero a través del archivo y solo luego muestra la última línea:

awk '/A1/ {print $NF}' file | tail -n1
Olaf Dietsche
fuente
14
Nunca necesita grep + awk ya que awk puede hacer su propia comparación RE. "grep A1 | awk '{print $ NF}'" debería ser simplemente "awk '/ A1 / {print $ NF}'". Además, si no está utilizando tail -f, entonces no necesita tail en absoluto, simplemente puede hacer: awk '/ A1 / {f = $ NF} END {print f}' file
Ed Morton
Esto no es del todo correcto, ya que es posible que la columna no aparezca en la ventana que Raw taille brinda. A menos que sepa que va a aparecer con cierta frecuencia, sería más seguro awk '/A1/ {print $NF}' file | tail -n1.
Mitchell Tracy
27

Para imprimir la última columna de una línea simplemente use $ (NF):

awk '{print $(NF)}' 
Gennadiy Zolotaryov
fuente
12

Una forma de usar awk:

tail -f file.txt | awk '/A1/ { print $NF }'
Steve
fuente
Pensé que era la solución correcta para el problema publicado (¡+1!) Pero ahora veo que no entiendo la pregunta. El OP quiere el último campo de la ÚLTIMA LÍNEA del archivo, pero no hay ÚLTIMA LÍNEA si está utilizando tail -f. Tal vez se refiere a la última línea ACTUALMENTE en el archivo, en cuyo caso vea uno de mis otros comentarios.
Ed Morton
Muy bueno y sencillo. Pulgares hacia arriba. Pulgares abajo para awkla sintaxis críptica :)
stamster
11

Puede hacer esto sin awk con solo algunas tuberías.

tac file | grep -m1 A1 | rev | cut -d' ' -f1 | rev
miono
fuente
Esto resuelve su problema, pero en realidad no usa awk. Espero que sea lo suficientemente bueno para ti de todos modos.
miono
4

tal vez esto funciona?

grep A1 file | tail -1 | awk '{print $NF}'
hgh
fuente
2

Puedes hacerlo todo en awk:

<file awk '$1 ~ /A1/ {m=$NF} END {print m}'
Thor
fuente
1
No necesita dividir () y una matriz, solo guarde el último campo e imprímalo: archivo awk '/ A1 / {f = $ NF} END {print f}'
Ed Morton
2

Usando Perl

$ cat rayne.txt
A1 123 456
B1 234 567
C1 345 678
A1 098 766
B1 987 6545
C1 876 5434


$ perl -lane ' /A1/ and $x=$F[2] ; END { print "$x" } ' rayne.txt
766

$
stack0114106
fuente
Parece demasiado complicado, solo hazloperl -lane 'print $F[2] if /A1/' rayne.txt
Hola Angel
1
@ Hola-Angel ... la pregunta pide la última aparición de A1. tu respuesta imprimirá todas las coincidencias ... por cierto, si te gusta mi respuesta, por favor
vótala
1

awk -F " " '($1=="A1") {print $NF}' FILE | tail -n 1

Usar awkcon el separador de campo -F establecido en un espacio "".

Use el patrón $1=="A1" y la acción {print $NF} , esto imprimirá el último campo en cada registro donde el primer campo es "A1". Canalice el resultado en la cola y use la -n 1opción para mostrar solo la última línea.

JimBob
fuente
0

Ejecute esto en el archivo:

awk 'ORS=NR%3?" ":"\n"' filename

y obtendrás lo que estás buscando.

Aziz
fuente
0

No es el problema real aquí, pero podría ayudar a alguien: estaba haciendo awk "{print $NF}", tenga en cuenta las citas incorrectas. Debería ser awk '{print $NF}', para que el caparazón no se expanda $NF.

delucasvb
fuente
-2

ls -l | awk '{print $9}' | tail -n1

Cristian
fuente
1
¿Cómo se relaciona esto con la pregunta del OP?
Hickory420