Я собираю презентацию для нетехнической аудитории. У меня есть программа, работающая в 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 ;
печатать красным цветом
ключевым моментом является то, что 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
для более подробной информации.