Проблемы с хвостом -f и awk? [Дубликат]

Если вы говорите о проверке формы, регулярное выражение для проверки правильного значения, а также правильных данных будет чрезвычайно сложным из-за разных стран и стандартов поставщиков.

Я интерпретирую этот вопрос как поиск широко допустимого шаблона, который может быть несовместим с внутренним состоянием, например, с допустимым набором чисел, но не подтверждая, что

Северная Америка проста, а для международных я предпочитаю использовать «идиоматический» шаблон, который охватывает способы, с помощью которых люди укажите и запомните их номера:

^((((\(\d{3}\))|(\d{3}-))\d{3}-\d{4})|(\+?\d{2}((-| )\d{1,8}){1,5}))(( x| ext)\d{1,5}){0,1}$

Североамериканский образец гарантирует, что если одна скобка включена, то и есть. Международные счета для необязательного первоначального «+» и кода страны. После этого вы находитесь в идиоме. Допустимыми совпадениями были бы:

  • (xxx)xxx-xxxx
  • (xxx)-xxx-xxxx
  • (xxx)xxx-xxxx x123
  • 12 1234 123 1 x1111
  • 12 12 12 12 12
  • 12 1 1234 123456 x12345
  • +12 1234 1234
  • +12 12 12 1234
  • +12 1234 5678
  • +12 12345678

Это может быть предвзятым, поскольку мой опыт ограничен Северной Америкой, Европой и небольшим количеством Азии.

597
задан Marcin 13 March 2015 в 12:00
поделиться

11 ответов

Включите режим буферизации строк grep при использовании BSD grep (FreeBSD, Mac OS X и т. д.)

tail -f file | grep --line-buffered my_pattern

Вам не нужно делать это для GNU grep (используется на почти любой Linux), поскольку он по умолчанию будет скрываться (YMMV для других Unix-подобных, таких как SmartOS, AIX или QNX).

1066
ответ дан Wes Mason 22 August 2018 в 05:01
поделиться
  • 1
    @MichaelNiemand вы можете использовать tail -F файл | grep -line-buffered my_pattern – jcfrei 26 May 2015 в 16:28
  • 2
    @MichaelGoldshteyn. Успокойся. Люди поддерживают это, потому что они находят эту страницу, когда они google & quot; grep line buffered & quot; и он решает проблему для них, которая не может быть точно такой, как вопрос. – raine 15 February 2016 в 20:31
  • 3
    Я пришел сюда, пытаясь вывести результат из strace. Без --line-buffered это не сработает. – sjas 11 September 2016 в 22:22
  • 4
    @MichaelGoldshteyn (и сторонники его комментария): у меня всегда была эта проблема с tail -f | grep, а --line-buffered решает ее для меня (на Ubuntu 14.04, GNU grep версии 2.16). Где «использовать буферизацию строки», если stdout является tty ». логика реализована? В git.savannah.gnu.org/cgit/grep.git/tree/src/grep.c , line_buffered задается только парсером аргументов. – Aasmund Eldhuset 9 January 2017 в 23:21
  • 5
    @MichaelGoldshteyn Я нахожусь на macOS, используя BSD grep и без --line-buffered Я не получаю никакого вывода. Однако, после тестирования, похоже, что GNU grep делает то, что вы описываете. Так что, как и большинство Unix, это зависит от реализации вашей платформы. Поскольку в вопросе не указана платформа, ваша информация оказывается ложной - после просмотра кода для BSD grep и сравнения его с GNU grep поведение определенно контролируется опцией -line-buffered. Просто по умолчанию только GNU grep сбрасывается. – Richard Waite 28 October 2017 в 22:37

Используйте awk (еще одна большая утилита bash) вместо grep, где у вас нет опции для буферизации строк! Он будет непрерывно передавать ваши данные из хвоста.

так вы используете grep

tail -f <file> | grep pattern

Вот как вы будете использовать awk

tail -f <file> | awk '/pattern/{print $0}'
-2
ответ дан Atif 22 August 2018 в 05:01
поделиться
  • 1
    Это неверно; Awk из коробки выполняет буферизацию строк, как и большинство других стандартных инструментов Unix. (Более того, {print $0} является избыточным, так как печать является действием по умолчанию при выполнении условия.) – tripleee 9 February 2015 в 15:00

Да, на самом деле все будет хорошо. Grep, и большинство команд Unix работают по потокам по одной строке за раз. Каждая строка, которая выходит из хвоста, будет анализироваться и передаваться, если она соответствует.

0
ответ дан Caleb 22 August 2018 в 05:01
поделиться
  • 1
    На самом деле это не так. Если grep является последней командой в цепочке труб, она будет действовать, как вы объясните. Однако, если он посередине, он будет буферизовать примерно 8 кбайт одновременно. – Mahmoud Al-Qudsi 18 February 2016 в 01:52

sed будет правильной командой ( stream editor)

tail -n0 -f <file> | sed -n '/search string/p'

, а затем, если вы хотите, чтобы команда tail вышла, как только вы нашли определенная строка:

tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'

Очевидно, что багизм: $ BASHPID будет идентификатором процесса команды tail. Команда sed следующая после хвоста в трубе, поэтому идентификатор процесса sed будет $ BASHPID + 1.

-1
ответ дан Christian Herr 22 August 2018 в 05:01
поделиться
  • 1
    Предполагается, что следующий процесс, запущенный в системе ($BASHPID+1), будет во многих ситуациях ложным, и это не помогает решить проблему буферизации, которая, вероятно, пытается спросить OP. В частности, рекомендация sed по сравнению с grep здесь кажется просто вопросом (сомнительным). (Вы можете получить p;q поведение с grep -m 1, если это то, что вы пытаетесь выполнить.) – tripleee 16 August 2017 в 09:17
  • 2
    – MUY Belgium 23 August 2018 в 10:33

В большинстве случаев вы можете tail -f /var/log/some.log |grep foo, и он будет работать нормально.

Если вам нужно использовать несколько grep в работающем файле журнала, и вы обнаружите, что вы не получаете выход, вам может понадобиться вставьте переключатель --line-buffered в средние grep (s), например:

tail -f /var/log/some.log | grep --line-buffered foo | grep bar
5
ответ дан Dale Anderson 22 August 2018 в 05:01
поделиться

Не видел, чтобы кто-то предлагал мои обычные варианты:

less +F <file>
ctrl + c
/<search term>
<enter>
shift + f

Я предпочитаю это, потому что вы можете использовать ctrl + c, чтобы останавливать и перемещаться по файлу всякий раз, а затем просто нажмите shift + f, чтобы вернуться к текущему потоковому поиску.

0
ответ дан Hans.Loven.work 22 August 2018 в 05:01
поделиться

Я все время использую tail -f <file> | grep <pattern>.

Он будет ждать до тех пор, пока grep не начнет снижаться, пока он не закончится (я использую Ubuntu).

104
ответ дан Irit Katriel 22 August 2018 в 05:01
поделиться
  • 1
    Это может длиться довольно долго, поэтому постарайтесь не терпеть. – glglgl 23 August 2011 в 14:41
  • 2
    Как долго это может потребоваться примерно? – Matthieu Napoli 23 August 2011 в 14:47
  • 3
    @Matthieu: зависит главным образом от того, для чего вы хотите, и насколько велики буферы в вашей ОС. Если grep соответствует только короткой строке каждые несколько часов, это будет за несколько дней до первого флеша. – tripleee 23 August 2011 в 14:53
  • 4
    Хвост не использует буферизацию вывода - grep делает. – XzKto 23 August 2011 в 15:02
  • 5
    Нет, grep не выполняет буферизацию вывода, когда выход идет на устройство tty, как ясно в этом ответе. Это делает буферизацию линии! Это правильный ответ и должен быть принятым ответом. Дополнительную информацию см. В моем более длинном комментарии к принятому в настоящее время ( неверному ) ответу. – Michael Goldshteyn 9 December 2015 в 18:23

Если вы хотите найти совпадения в файле whole (а не только в хвосте), и вы хотите, чтобы он сидел и ждал новых совпадений, это прекрасно работает:

tail -c +0 -f <file> | grep --line-buffered <pattern>

Флаг -c +0 указывает, что выход должен начинаться с 0 байт (-c) с начала (+) файла.

4
ответ дан Ken Williams 22 August 2018 в 05:01
поделиться

вы можете рассмотреть этот ответ как улучшение .. Обычно я использую

tail -F <fileName> | grep --line-buffered  <pattern> -A 3 -B 5

-F лучше в случае поворота файла (-f не будет работать должным образом, если файл повернут)

-A и -B полезно для получения строк непосредственно перед и после появления шаблона. Эти блоки появятся между разделителями пунктирных линий

1
ответ дан mebada 22 August 2018 в 05:01
поделиться
  • 1
    grep -C 3 <pattern>, заменяет -A & lt; N & gt; и -B & lt; N & gt; если N равно. – Arun Sangal 2 March 2017 в 01:45

Я думаю, что ваша проблема в том, что grep использует некоторую буферизацию вывода. Попробуйте

tail -f file | stdbuf -o0 grep my_pattern

, он установит режим буферизации вывода grep в небуферизованный.

50
ответ дан XzKto 22 August 2018 в 05:01
поделиться
  • 1
    И это имеет то преимущество, что его можно использовать для многих других команд, кроме grep. – Peter V. Mørch 5 July 2012 в 12:08
  • 2
    Однако, как я выяснил, после того, как вы сыграли больше с ним, некоторые команды только очищают свой вывод при подключении к tty, и для этого unbuffer (в пакете expect-dev на debian) king . Поэтому я бы использовал unbuffer поверх stdbuf. – Peter V. Mørch 7 July 2012 в 20:41
  • 3
    @Peter V. Mørch Да, вы правы, unbuffer может иногда работать там, где stdbuf не может. Но я думаю, вы пытаетесь найти магическую программу, которая всегда будет решать ваши проблемы, а не понимать вашу проблему. Создание виртуального tty - это несвязанная задача. Stdbuf делает именно то, что мы хотим (устанавливает стандартный выходной буфер, чтобы дать значение), в то время как unbuffer делает много скрытых вещей, которые нам не нужны (сравните интерактивные top с stdbuf и unbuffer). И на самом деле нет «волшебного» решения: иногда небуффер не работает, например, awk использует другую реализацию буфера (stdbuf тоже не сработает). – XzKto 9 July 2012 в 08:48
  • 4
    «Но я думаю, вы пытаетесь найти« магическую »программу, которая всегда будет решать ваши проблемы, а не понимать вашу проблему. & quot; - Я думаю ты прав! ;-) – Peter V. Mørch 10 July 2012 в 09:27
  • 5
    Дополнительная информация о stdbuf, `unbuffer и stdio буферизации в pixelbeat.org/programming/stdio_buffering – Tor Klingberg 27 April 2015 в 14:45
0
ответ дан user10584393 5 November 2018 в 03:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: