Простой способ различать файлы журнала, игнорируя отметки времени? - PullRequest
36 голосов
/ 04 сентября 2008

Мне нужно различить два файла журнала, но игнорировать часть метки времени каждой строки (первые 12 символов, чтобы быть точными). Есть ли хороший инструмент или умная команда awk, которая может мне помочь?

Ответы [ 5 ]

43 голосов
/ 04 сентября 2008

В зависимости от используемой вами оболочки вы можете превратить предложенный подход @ Blair в 1-строчный

diff <(cut -b13- file1) <(cut -b13- file2)

(от + 1 до @ Blair для оригинального предложения: -)

19 голосов
/ 04 сентября 2008

@ EbGreen сказал

Я бы просто взял файлы журнала и убрал метки времени с начала каждой строки, а затем сохранил файл в разных файлах. Затем сравните эти файлы.

Это, вероятно, лучшая ставка, если только у вашего инструмента нет специальных способностей. Например, вы могли бы

cut -b13- file1 > trimmed_file1
cut -b13- file2 > trimmed_file2
diff trimmed_file1 trimmed_file2

См. Ответ @ toolkit для оптимизации, которая делает его однострочным и устраняет необходимость в дополнительных файлах. Если ваша оболочка это поддерживает. Bash 3.2.39 как минимум кажется ...

9 голосов
/ 21 ноября 2013

Ответы, использующие cut, хороши, но иногда сохраняются временные метки в пределах вывода diff. Поскольку вопрос ОП касается игнорирования отметок времени (не удаляя их), я поделюсь здесь своей хитрой командной строкой:

diff -I '^#' <(sed -r 's/^((.){12})/#\1\n/' 1.log) <(sed -r 's/^((.){12})/#\1\n/' 2.log)
  • sed выделяет временные метки (# до и \n после) в замене процесса
  • diff -I '^#' игнорирует линии, имеющие эти временные метки (строки начинаются с #)

пример

Два файла журнала, имеющие одинаковое содержимое, но разные временные метки:

$> for ((i=1;i<11;i++)) do echo "09:0${i::1}:00.000 data $i"; done > 1.log
$> for ((i=1;i<11;i++)) do echo "11:00:0${i::1}.000 data $i"; done > 2.log

Basic diff командная строка говорит, что все строки разные:

$> diff 1.log 2.log
1,10c1,10
< 09:01:00.000 data 1
< 09:02:00.000 data 2
< 09:03:00.000 data 3
< 09:04:00.000 data 4
< 09:05:00.000 data 5
< 09:06:00.000 data 6
< 09:07:00.000 data 7
< 09:08:00.000 data 8
< 09:09:00.000 data 9
< 09:01:00.000 data 10
---
> 11:00:01.000 data 1
> 11:00:02.000 data 2
> 11:00:03.000 data 3
> 11:00:04.000 data 4
> 11:00:05.000 data 5
> 11:00:06.000 data 6
> 11:00:07.000 data 7
> 11:00:08.000 data 8
> 11:00:09.000 data 9
> 11:00:01.000 data 10

Наш хитрый diff -I '^#' не отображает никакой разницы (метки времени игнорируются):

$> diff -I '^#' <(sed -r 's/^((.){12})/#\1\n/' 1.log) <(sed -r 's/^((.){12})/#\1\n/' 2.log)
$>

Измените 2.log (замените data на foo в 6-й строке) и проверьте еще раз:

$> sed '6s/data/foo/' -i 2.log
$> diff -I '^#' <(sed -r 's/^((.){12})/#\1\n/' 1.log) <(sed -r 's/^((.){12})/#\1\n/' 2.log)
11,13c11,13
11,13c11,13
< #09:06:00.000
<  data 6
< #09:07:00.000
---
> #11:00:06.000
>  foo 6
> #11:00:07.000

=> временные метки хранятся на выходе diff!

Вы также можете использовать функцию рядом , используя опцию -y или --side-by-side:

$> diff -y -I '^#' <(sed -r 's/^((.){12})/#\1\n/' 1.log) <(sed -r 's/^((.){12})/#\1\n/' 2.log)
#09:01:00.000                   #11:00:01.000
 data 1                          data 1
#09:02:00.000                   #11:00:02.000
 data 2                          data 2
#09:03:00.000                   #11:00:03.000
 data 3                          data 3
#09:04:00.000                   #11:00:04.000
 data 4                          data 4
#09:05:00.000                   #11:00:05.000
 data 5                          data 5
#09:06:00.000                 | #11:00:06.000
 data 6                       |  foo 6
#09:07:00.000                 | #11:00:07.000
 data 7                          data 7
#09:08:00.000                   #11:00:08.000
 data 8                          data 8
#09:09:00.000                   #11:00:09.000
 data 9                          data 9
#09:01:00.000                   #11:00:01.000
 data 10                         data 10

старый sed

Если ваша реализация sed не поддерживает опцию -r, возможно, вам придется посчитать двенадцать точек <(sed 's/^\(............\)/#\1\n/' 1.log) или использовать другой шаблон по вашему выбору;)

3 голосов
/ 02 июня 2015

Для графического варианта Meld может сделать это, используя функцию текстовые фильтры .

Позволяет игнорировать строки, основанные на одном или нескольких регулярных выражениях Python. Различия все еще появляются, но строки, которые не имеют других отличий, не будут выделены.

Example configuration

2 голосов
/ 19 октября 2015

Используйте Kdiff3 и на Сконфигурируйте> Различия отредактируйте команду Line-Matching Preprocessor"примерно так:

sed "s/[ 012][0-9]:[0-5][0-9]:[0-5][0-9]//"

Это отфильтровывает временные метки из алгоритма выравнивания сравнения.

Kdiff3 также позволяет вручную выравнивать определенные линии .

...