Лично мой любимый (требует bash и других вещей, которые являются стандартными в большинстве дистрибутивов Linux)
Детали могут сильно зависеть от того, что выдают две вещи и как вы хотите объединить их ...
Содержимое command1 и command2 друг за другом в выводе:
cat <(command1) <(command2) > outputfile
Или, если обе команды выводят альтернативные версии одних и тех же данных, которые вы хотите видеть рядом (я использовал это с snmpwalk; числа с одной стороны и имена MIB с другой):
paste <(command1) <(command2) > outputfile
Или, если вы хотите сравнить выходные данные двух похожих команд (например, найти в двух разных каталогах)
diff <(command1) <(command2) > outputfile
Или, если они упорядочены какие-то результаты, объедините их:
sort -m <(command1) <(command2) > outputfile
Или запустите обе команды одновременно (хотя, возможно, немного перемешайте):
cat <(command1 & command2) > outputfile
Оператор <() устанавливает именованный канал (или / dev / fd) для каждой команды, направляя вывод этой команды в именованный канал (или ссылку на файл-указатель / dev / fd) и передает имя в командной строке. Есть эквивалент с> (). Вы можете сделать: command0 | tee >(command1) >(command2) >(command3) | command4
одновременно отправить вывод одной команды, например, 4 другим командам.
grep --line-buffered
- удобно для одновременноgrep
«тtail
из нескольких файлов журналов. см. stackoverflow.com/questions/10443704/line-buffered-catКак
cat
показывает горилла, вы можете добавить две пары к другой с помощьюВы также можете создать FIFO, направить вывод команд на него, а затем прочитать из FIFO с помощью любой другой программы:
Особенно полезно для программ, которые только пишут или читают файл, или для микширования программ, которые выводят только стандартный вывод / файл с одной, которая поддерживает только другую.
источник
/tmp/p1
и/tmp/p2
ваши входные каналы, а/tmp/output
выходной.источник
()
сбрасывают свои выходные данные в каждой строке (и некоторые другие неясные правила POSIX для атомарности), вы можетеДля этого я создал специальную программу: fdlinecombine
Он читает несколько каналов (обычно программные выходы) и записывает их в стандартный вывод (вы также можете переопределить разделитель)
источник
Действительно классная команда, которую я использовал для этого
tpipe
, вам, возможно, придется скомпилировать, потому что она не такая распространенная. Он отлично подходит для того, чтобы делать именно то, о чем вы говорите, и он настолько чистый, что я обычно его устанавливаю. Справочная страница находится здесь http://linux.die.net/man/1/tpipe . Список загруженных файлов находится в этом архиве http://www.eurogaran.com/downloads/tpipe/ .Это используется так,
источник
Будьте осторожны здесь; простое их отслеживание приведет к тому, что результаты будут смешиваться так, как вы этого не хотите: например, если они представляют собой файлы журнала, вы, вероятно, не хотите, чтобы строка от одного вставлялась на полпути через строку от другого. Если это нормально, тогда
будет работать. Если это не так , то вам нужно найти что-то, что будет выполнять буферизацию строк и выводить только полные строки. Системный журнал делает это, но я не уверен, что еще могло бы.
РЕДАКТИРОВАТЬ: оптимизация для небуферизованного чтения и именованных каналов:
рассматривая / tmp / p1, / tmp / p2, / tmp / p3 как именованные каналы, созданные "mkfifo / tmp / p N "
теперь, таким образом, мы можем прочитать вывод именованного канала "/ tmp / p3" без буферизации :
Существует небольшая ошибка сортировки, вам нужно «инициализировать» 1-й канал ввода / tmp / p1:
для того, чтобы tail примет вход от 2-го канала / tmp / p2 и не будет ждать, пока что-нибудь придет в / tmp / p1. это может быть не так, если вы уверены, что / tmp / p1 сначала получит ввод.
Также опция -q необходима для того, чтобы tail не печатал мусор с именами файлов.
источник
tail -q -f /tmp/p1 /tmp/p2 | awk '{print $0 > "/tmp/p3"; close("/tmp/p3"); fflush();}' &
теперь / TMP / p3 может быть даже назван труба , и вы можете прочитать его, простоtail -f /tmp/p3
все это UnBuffered = построчно есть однако небольшая ошибка из рода. 1-й файл / именованный канал должен быть инициализирован первым, чтобы tail принял выходные данные 2-го. так что вам нужно будетecho -n > /tmp/p1
и чем все будет работать гладко.Лучшая программа для этого
lmerge
. В отличие от ответа freihart, он ориентирован на строки, поэтому выходные данные двух команд не будут перекрывать друг друга. В отличие от других решений, он объединяет входные данные, поэтому ни одна команда не может доминировать в выходных данных. Например:Дает вывод:
источник