Чи є інструмент, який прозоро поєднує zcat та cat?


70

Під час обробки файлів журналів деякі закінчуються як gzipped файли завдяки, logrotateа інші - ні. Тож коли ви спробуєте щось подібне:

$ zcat *

ви закінчуєте командний рядок, як, zcat xyz.log xyz.log.1 xyz.log.2.gz xyz.log.3.gzа потім:

gzip: xyz.log: not in gzip format

Чи є інструмент, який буде приймати магічні байти, подібні до того, як це fileпрацює, і використовувати zcatабо catзалежно від результату, щоб я міг подати висновок, grepнаприклад?

NB: Я знаю, що можу це сценарій, але я запитую, чи є вже інструмент там.

Відповіді:


41

zless

Здається, шкода zcat, оскільки у libz є API, який підтримує зчитування з стислих та нестиснених файлів прозоро. Але на сторінці написано, що zcatце рівнозначно gunzip -c.


Дякую за цю альтернативу. Я міг би подумати про це, чи не можу? ;) ... Ну добре. Знайдіть +1 і прийміть (також тому, що у вас менше представників, ніж у іншого відповідача).
0xC0000022L

Дивовижний. Допомогли мені дуже багато, я використовував скрипт оболонки, щоб вирішити це протягом багатьох років ... або жахливий сценарій Perl ... злиття розв’язання журналу, який використовується awstats ... тепер я знаю цей дивовижний інструмент. Дякую.
Лучано Андресс Мартіні

98

Спробуйте -fабо --force:

zcat -f -- *

Так як zcatце просто простий сценарій, який працює

exec gzip -cd "$@"

з довгими варіантами, які перекладалися б на

exec gzip --stdout --decompress "$@"

і, відповідно до man gzip(підкресли мою):

-f - сила
      Примушуйте стискати чи декомпресувати, навіть якщо файл має кілька посилань
      або відповідний файл вже існує, або якщо стислі дані
      читати з або записувати в термінал. Якщо вхідні дані не у форматі
      розпізнається gzip, і якщо також вказано параметр --stdout, скопіюйте
      вхідні дані без зміни стандартного виводу: нехай zcat поводиться як кіт .

Також:

так що я можу подати висновок, grepнаприклад

Ви можете використовувати zgrepдля цього:

zgrep -- PATTERN *

хоча дивіться коментар Стефана нижче.


1
Дякую, це цікава альтернатива zlessрішення. Приємно і +1.
0xC0000022L

6
Зауважте, що обидва zlessі zgrepє сценаріями, які дзвонять gzip -cdfq(тобто zcat -fq).
Стефан Шазелас

9

Я використовую точно з тією ж метою:

{ cat /var/log/messages ; zcat /var/log/messages*.gz ; }| grep something | grep "something else" ....

Мені подобається такий підхід, тому що він вимагає найменшого часу, витраченого на освіту колег. Якщо повідомлення журналу мають часову позначку у другій часовій марці, це особливо корисно.
Томас Л Холадей

Відмінний підхід. Дякую.
Мілош Джаконович

7

Існує заміна заміни для ztools (zcat, zgrep, ..) під назвою zutils, яка об'єднує всі інструменти декомпресії незалежно від бекенда. Тож з тією ж командою ви можете прозоро читати файли lzma, gzipped, xz.

Він доступний у дебіанських хрипких або новіших, ймовірно, також у redhat / centos.

Сторінка проекту знаходиться тут nongnu.org

Повідомлення в блозі з поясненням використання утиліти тут ( noone.org )


3

Це чудово працює в RHEL 5.x, де zcat є двійковим. Він виходить з ладу в RHEL 6.x (і Ubuntu 12.x), де zcat є скриптом. Це звично працювало.

Я б не використовував zcat взагалі, але zgrep не буде належним чином обробляти нестиснені файли.


2

Відкриває як стиснене, так і нестиснене, у хронологічному порядку.

ls -v syslog* | tac | xargs zcat -f | less

Він дає неправильний порядок із більш ніж десятьма файлами журналів (syslog.10.gz ...)
Vanni,

Хороший улов. -в повинен це виправити.
Райан

ls -rvуникати tac. Щодо файлів журналу, less $(ls -rv syslog*)ваш LESSOPENENV Var належним чином працює добре. Ви можете здійснювати пошук по файлах, esc-nщоб знайти наступну відповідність, ігноруючи межі файлів.
Пітер Кордес

С zsh:zcat -f syslog*(nOn)
Стефан Шазелас

Це не спрацьовує, якщо на наступний день у вас встановлено обертання журналу
cjbarth

1

Що з обгорткою?

$ cat xcat.sh 
#!/bin/bash

for i in $@;do 
        [ ! -z "$(file -i $i | grep "gzip")" ] && zcat $i || cat $i
done

$ bash xcat.sh plain.txt gzipped_text.gz

0

Скопіюйте та вставте (або покладіть її в кінці ~/.bashrcфайлу) цю функцію bash :

logs() { zcat -f $(ls -rv "$1"*) | less; }

Тепер ви можете набрати наприклад logs /var/log/syslogабо logs /var/log/nginx/access.logпереглянути всі повідомлення журналу syslog або nginx від найдавніших до найновіших з меншою кількістю .

Ви можете шукати що - то друкувати /somethingі натиснувши nна наступний .


0

Існує прекрасний сценарій Perl, який саме це робить. Це logresolvemerge.pl з проекту awstats: http://www.awstats.org/docs/awstats_tools.html

Logresolvemerge дозволяє отримати один унікальний вихідний файл журналу, відсортований за датою, побудований з конкретних джерел:

  • Він може прочитати кілька вхідних файлів журналу
  • Він може читати файли журналу .gz / .bz2

    Вихід є STDOUT, так що ви можете досить добре використовувати його в додаткових процесах.


  • 0

    Спираючись на відповідь @ Ryan, наступне отримає отримання всіх "прокатаних" файлів, відсортованих за алфавітом, потім отримайте поточний файл, розпакуйте їх, якщо потрібно, та lessїх:

    cat <(ls mylog.log-* | sort) <(ls mylog.log) | xargs zcat -f | less

    або якщо ви хочете отримати їх все як безперервний потік, ви можете tailїх і, за бажанням, передати їх іншому процесу

    cat <(ls mylog.log-* | sort | xargs zcat -f) <(tail -f -n +0 mylog.log)

    Слід зазначити, що це розроблено для журналів, які щодня обертаються з датою, доданою до кінця файлу. Якщо ваш журнал у нас інший формат, вам доведеться змінити першу частину catзаяви, щоб вмістити її.

    Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
    Licensed under cc by-sa 3.0 with attribution required.