Показывать имя файла в начале каждой строки при одновременном подборе нескольких файлов?


14

при одновременной настройке нескольких файлов, как показано ниже, есть ли способ показать имя файла в начале каждой строки?

tail -f one.log two.log

токовый выход

==> one.log <==
contents of one.log here...
contents of one.log here...

==> two.log <==
contents of one.log here...
contents of two.log here..

Ищу что-то вроде

one.log: contents of one.log here...
one.log: contents of one.log here...
two.log: contents of two.log here...
two.log: contents of two.log here...

Вы можете посмотреть на -v(подробный) вариант хвоста. Это может не совсем соответствовать вашему запросу, но это только начало.
Рахул

multitail может сделать это, я думаю
Жиль "ТАК - перестань быть злым"

Ответы:


7
tail  -f ...your-files | 
    awk '/^==> / {a=substr($0, 5, length-8); next}
                 {print a":"$0}'

\ спасибо {don_cristti}


@don_crissti, спасибо! (1) против файла - больше нет вина в мой стакан! (2) хорошая идея. Я начинаю делать что-то вроде этого, но я лениво сказал себе: «Никто не сделает хвост из файлов с пробелами» :) - Я буду использовать ваши отличные предложения.
Жоао

Вы можете объяснить длину 8? почему здесь 8, я знаю только 8 работ.
Шичен Го

1
tail -n 1 * .txt | awk '/ ^ ==> / {a = substr ($ 0,5, длина-8); следующая} {print a, $ 1} '| awk '$ 2> 0 {if ($ 2! ~ / chrY /) print $ 1}' | xargs -I {} qsub {}
Шичен Го

@ShichengGuo, 8 = длина ("==>") + длина ("<==")
Цзяо

1
удивительно / удивительно ваше волшебное awkрешение joojoo работает!
Тревор Бойд Смит

6

Короткий ответ

В GNU Parallel есть множество приятных опций, которые позволяют очень легко делать такие вещи:

parallel --tagstring "{}:" --line-buffer tail -f {} ::: one.log two.log

Выход будет:

one.log: содержимое one.log здесь ...
one.log: содержимое one.log здесь ...
two.log: содержимое файла two.log здесь ...
two.log: содержимое файла two.log здесь ...

Больше объяснений

  • Опция --tagstring=strпомечает каждую строку вывода строкой str . Изparallel man-страницы :
--tagstring str
                Строки тегов со строкой. Каждая строка вывода будет дополнена
                ул и таб (\ т). str может содержать замещающие строки, такие как {}.

                --tagstring игнорируется при использовании -u, --onall и --nonall.
  • Все вхождения {}будут заменены аргументами параллели, которые в данном случае являются именами файлов журнала; т.е. one.logи two.log(все аргументы после :::).

  • Опция --line-bufferобязательна, потому что вывод команды (например, tail -f one.logили tail -f two.log) будет напечатан, если эта команда завершена. Так как tail -fбудет ждать роста файла, необходимо распечатать вывод в виде строки, что --line-bufferделает это. Снова из parallel справочной страницы :

--line-buffer (альфа-тестирование)
                Вывод буфера на линейной основе. --group сохранит вывод
                вместе для всей работы. --ungroup позволяет смешивать вывод с
                половина строки от одной работы и половина строки от
                другая работа. --line-buffer подходит между этими двумя: GNU параллельно
                напечатает полную строку, но позволит смешивать строки
                разные работы.

2

Если tailэто не обязательно, вы можете использовать grepдля этого:

grep "" *.log

Это напечатает имя файла как префикс каждой строки вывода.

Выходные данные прерываются, если *.logрасширяется только до одного файла. В этом отношении:

grep '' /dev/null *.log

Мне нужно показать имя файла в выводе tail -fnot grep.
МТК

@serenesat это просто напечатало бы все содержимое файлов, не так ли? ОП просила напечатать имя файла, когда указан хвост
rahul

Вы также можете просто сделать --with-filenameили -Hвсегда форсировать имя файла.
Тревор Бойд Смит

я действительно люблю этот ответ! делает именно то, что нужно с решением длиной 13 символов. в отличие от хитрого awkрешения или parallelкоторое не установлено.
Тревор Бойд Смит

Единственная проблема заключается в том, что если ваши лог-файлы имеют длину 1 миллион строк. тогда ваш grep спамит 1 миллион строк в консоль (или более ssh) ...
Тревор Бойд Смит

0

Моя идея состоит в том, чтобы создать один файл с объединенными журналами из нескольких файлов, как кто-то предложил здесь, и добавить имена файлов:

$ tail -f /var/log/syslog | sed -u -E 's,(^.+$),/var/log/syslog: \1,g' >> /tmp/LOG &&
$ tail -f /var/log/Xorg.0.log | sed -u -E 's,(^.+$),/var/log/Xorg.0.log: \1,g' >> /tmp/LOG &&
$ tail -f /tmp/LOG

0

Что-то с xargsи sedможет работать:

$ xargs -I% -P0 sh -c "tail -f % | sed s/^/%:/g" <<EOT
one.log
two.log
EOT
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.