Imprimindo a última coluna de uma linha em um arquivo

135

Eu tenho um arquivo que está sendo gravado constantemente para / atualizado. Quero encontrar a última linha que contém uma palavra específica e, em seguida, imprimir a última coluna dessa linha.

O arquivo se parece com isso. Mais linhas A1 / B1 / C1 serão anexadas a ela ao longo do tempo.

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

Eu tentei usar

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

para imprimir o valor 766, mas nada é produzido.

Existe uma maneira de fazer isso?

Rayne
fonte

Respostas:

199

Você não vê nada, por causa do buffer. A saída é mostrada quando há linhas suficientes ou o final do arquivo é atingido. tail -fsignifica esperar por mais entradas, mas não há mais linhas filee, portanto, o tubo para grepnunca é fechado.

Se você omitir -fda tailsaída é mostrado imediatamente:

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

@ EdMorton está certo, é claro. O Awk também pode procurar A1, o que reduz a linha de comando para

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

ou sem cauda, ​​mostrando a última coluna de todas as linhas que contêm A1

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

Graças ao comentário de @ MitchellTracy, você tailpode perder o registro que contém A1e, portanto, você não obtém nenhuma saída. Isso pode ser resolvido alternando taile awkpesquisando primeiro o arquivo e só depois mostrando a última linha:

awk '/A1/ {print $NF}' file | tail -n1
Olaf Dietsche
fonte
14
Você nunca precisa de grep + awk, pois o awk pode fazer sua própria comparação de RE. "grep A1 | awk '{print $ NF}'" deve ser apenas "awk '/ A1 / {print $ NF}'". Além disso, se você não estiver usando o tail -f, não precisará do tail: yoiu pode fazer: awk '/ A1 / {f = $ NF} END {print f}'
Ed Morton
Isso não está certo, pois a coluna pode não aparecer na janela que o raw tailfornece. A menos que você saiba que ele aparecerá com uma certa frequência, seria mais seguro awk '/A1/ {print $NF}' file | tail -n1.
Mitchell Tracy
27

Para imprimir a última coluna de uma linha, basta usar $ (NF):

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

Uma maneira de usar awk:

tail -f file.txt | awk '/A1/ { print $NF }'
Steve
fonte
Eu pensei que era a solução certa para o problema publicado (+1!), Mas agora vejo que não entendi a pergunta. O OP quer o último campo da ÚLTIMA LINHA do arquivo, mas não há ÚLTIMA LINHA se você estiver usando tail -f. Talvez ele esteja falando da última linha ATUALMENTE no arquivo; nesse caso, veja um dos meus outros comentários.
Ed Morton
Muito bom e simples. Afirmativo. Polegares para baixo para awka sintaxe enigmática de :) :)
stamster
11

Você pode fazer isso sem awk com apenas alguns tubos.

tac file | grep -m1 A1 | rev | cut -d' ' -f1 | rev
miono
fonte
Isso resolve seu problema, mas na verdade não usa o awk. Espero que seja bom o suficiente para você de qualquer maneira.
Miono 24/10/12
4

talvez isso funcione?

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

Você pode fazer tudo isso em awk:

<file awk '$1 ~ /A1/ {m=$NF} END {print m}'
Thor
fonte
1
Você não precisa de split () e uma matriz, apenas salve o último campo e imprima o arquivo: 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
fonte
Parece muito complicado, basta fazerperl -lane 'print $F[2] if /A1/' rayne.txt
Hi-Angel
1
@ Hi-Angel .. a pergunta pede a última ocorrência de A1. a sua resposta irá imprimir todos os jogos .. btw se você gosta de minha resposta, pls upvote-lo
stack0114106
1

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

Use awkcom o separador de campos -F definido como um espaço "".

Use o padrão $1=="A1" e a ação {print $NF} , isso imprimirá o último campo em todos os registros em que o primeiro campo seja "A1". Canalize o resultado na cauda e use a -n 1opção para mostrar apenas a última linha.

JimBob
fonte
0

Execute isso no arquivo:

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

e você conseguirá o que está procurando.

Aziz
fonte
0

Não é o problema real aqui, mas pode ajudar alguém: eu estava fazendo awk "{print $NF}", observe as aspas erradas. Deve ser awk '{print $NF}', para que o shell não se expanda $NF.

delucasvb
fonte
-2

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

Cristian
fonte
1
Como isso está relacionado à pergunta do OP?
Hickory420 27/05/19