Intereting Posts

Как использовать sed для управления потоковым потоком?

Я собираю презентацию для нетехнической аудитории. У меня есть программа, работающая в bash, которая выводит непрерывный поток значений, некоторые из которых важны. Я хотел бы выделить важные результаты, поскольку они отображаются, чтобы зрители могли понять их частоту. Проблема в том, что я не могу заставить sed работать на запущенном потоке. Он отлично работает, если я помещаю результаты в файл, как в:

 cat output.txt | sed "s/some text/some text bolded/" 

Но если я попытаюсь сделать то же самое на текущем выходе, вот так:

 command | sed "s/some text/some text bolded/" 

sed ничего не делает. Есть предположения?

Поскольку Ламберт был достаточно полезен, чтобы указать, мое высказывание о том, что sed ничего не делает, было неопределенным. Что происходит, так это то, что программа выводит на stdout (я уверен, что это не запись в stderr ), как это обычно бывает, даже если она передается через sed .

Проблема состоит в том, что команда вызывает вторую программу, которая затем выводит на stdout. В первой программе напечатано несколько строк; это я могу редактировать. Затем есть поток значений, напечатанный второй программой; я не могу редактировать.

Perl и awk методы тоже не работают.

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

Чтобы заставить команду не unbuffer свой вывод, вы можете использовать unbuffer (from expect) или stdbuf (от GNU coreutils).

 unbuffer command | sed … stdbuf -o0 command | sed … 

Я бы использовал awk

  command | awk '/some important stuff/ { printf "%c[31m%s%c[0m\n",27,$0,27 ; next } { print ; } ' 

где

  • /some important stuff/ выберите важную строку, например, в sed
  • printf "%c[31m%s%c[0m\n",27,$0,27 ; печатать красным цветом
    • используйте 32,33 для зеленого, желтого …
    • $ 1, $ 2, можно использовать для выбора определенного поля
  • другая строка только что напечатана «как есть»,

ключевым моментом является то, что command должна смывать строки, но это должно быть так, если у вас много выходных данных.

Перл:

 command | perl -pe 's/(stuff)/\x1b[1m$1\x1b[0m/g' 

или с непрерывным выходом:

Сценарий bash для вывода:

 #!/bin/bash while [ true ] do echo "Some stuff" done 

Тест с:

 ./cont | perl -pe 's/(stuff)/\x1b[1m${1}\x1b[0m/g' 
  • \x1b[1m – жирная или увеличенная интенсивность
  • ${1} – backreferenze
  • \x1b[0m – сбросить все атрибуты

Вывод:

Некоторые вещи
Некоторые вещи
Некоторые вещи
Некоторые вещи

Здесь больше кодов выхода.

sed имеет для этого вариант:

-u, –unbuffered

Которая загружает минимальные объемы данных из входных файлов и чаще очищает выходные буферы. См. man sed для более подробной информации.