Печать последнего столбца строки в файле


137

У меня есть файл, который постоянно пишется / обновляется. Я хочу найти последнюю строку, содержащую определенное слово, а затем распечатать последний столбец этой строки.

Файл выглядит примерно так. Со временем к нему будут добавлены новые строки A1 / B1 / C1.

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

Я пытался использовать

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

для печати значения 766, но ничего не выводится.

Есть ли способ сделать это?

Ответы:


203

Вы ничего не видите из-за буферизации. Вывод отображается, когда имеется достаточно строк или достигнут конец файла. tail -fозначает ожидание ввода, но в нем больше нет строк, fileпоэтому канал grepникогда не закрывается.

Если опустить -fот tailвыхода сразу показывается:

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

@EdMorton, конечно, прав. Awk также может искать A1, что сокращает командную строку до

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

или без хвоста, показывая последний столбец всех строк, содержащих A1

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

Благодаря комментарию @MitchellTracy, вы tailможете пропустить содержащуюся запись A1и, таким образом, вы не получите никакого вывода. Это может быть решено переключением tailи awk, поиском сначала по файлу и только потом показом последней строки:

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

15
Вам никогда не понадобится grep + awk, поскольку awk может выполнять собственное сравнение RE. "grep A1 | awk '{print $ NF}'" должно быть просто "awk '/ A1 / {print $ NF}'". Кроме того, если вы не используете tail -f, тогда вам вообще не нужен tail, вы можете просто сделать: awk '/ A1 / {f = $ NF} END {print f}' file
Ed Morton

1
Это не совсем правильно, поскольку столбец может не отображаться в окне, которое tailдает вам raw . Было бы безопаснее, если вы не знаете, что он будет появляться с определенной частотой awk '/A1/ {print $NF}' file | tail -n1.
Митчелл Трейси


12

Один из способов использования awk:

tail -f file.txt | awk '/A1/ { print $NF }'

Я думал, что это правильное решение опубликованной проблемы (+1!), Но теперь я вижу, что не понимаю вопроса. OP хочет последнее поле из ПОСЛЕДНЕЙ СТРОКИ файла, но ПОСЛЕДНЯЯ СТРОКА отсутствует, если вы используете tail -f. Может быть, он имеет в виду последнюю строку ТЕКУЩЕГО в файле, и в этом случае посмотрите один из моих других комментариев.
Эд Мортон

Очень хорошо и просто. Недурно. Недурно за awkзагадочный синтаксис :)
stamster

11

Вы можете сделать это без awk, используя лишь несколько каналов.

tac file | grep -m1 A1 | rev | cut -d' ' -f1 | rev

Это решает вашу проблему, но на самом деле awk не используется. Надеюсь, вам этого хватит.
miono

4

может это работает?

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

2

Вы можете сделать все это в awk:

<file awk '$1 ~ /A1/ {m=$NF} END {print m}'

1
Вам не нужны split () и массив, просто сохраните последнее поле и распечатайте его: awk '/ A1 / {f = $ NF} END {print f}' file
Эд Мортон

2

Использование 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

$

Выглядит слишком сложно, просто сделайтеperl -lane 'print $F[2] if /A1/' rayne.txt
Hi-Angel

1
@ Hi-Angel .. вопрос касается последнего появления A1. в вашем ответе будут напечатаны все совпадения .. кстати, если вам нравится мой ответ, пожалуйста, проголосуйте за него
stack0114106

1

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

Используйте awkс разделителем полей -F, установленным на пробел "".

Используйте шаблон $1=="A1" и действие {print $NF} , это напечатает последнее поле в каждой записи, где первое поле - «A1». Вставьте результат в хвост и используйте -n 1опцию, чтобы показать только последнюю строку.


0

Выполните это в файле:

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

и вы получите то, что ищете.


0

Это не настоящая проблема, но может помочь кому-то: я делал awk "{print $NF}", обратите внимание на неправильные цитаты. Должно быть awk '{print $NF}', чтобы оболочка не расширялась $NF.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.