Pregunta

Necesito diferenciar dos archivos de registro pero ignorar la parte de la marca de tiempo de cada línea (los primeros 12 caracteres para ser exactos).¿Existe una buena herramienta o un comando awk inteligente que pueda ayudarme?

¿Fue útil?

Solución

Dependiendo del shell que esté utilizando, puede cambiar el enfoque @Blair sugerido en una sola línea

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

(+1 a @Blair por la sugerencia original :-)

Otros consejos

@EbGreen dijo

Simplemente tomaría los archivos de registro y eliminaría las marcas de tiempo del inicio de cada línea y luego guardaría el archivo en archivos diferentes.Luego diferencia esos archivos.

Probablemente esa sea la mejor opción, a menos que su herramienta de diferenciación tenga poderes especiales.Por ejemplo, podrías

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

Consulte la respuesta de @toolkit para conocer una optimización que lo convierte en una sola línea y evita la necesidad de archivos adicionales.Si su shell lo admite.Bash 3.2.39 al menos parece...

Respuestas usando cut están bien, pero a veces mantienen las marcas de tiempo dentro del diff la producción es apreciable.Como la pregunta del OP es sobre ignorando las marcas de tiempo (sin eliminarlos), comparto aquí mi complicada línea de comando:

diff -I '^#' <(sed -r 's/^((.){12})/#\1\n/' 1.log) <(sed -r 's/^((.){12})/#\1\n/' 2.log)
  • sed aísla las marcas de tiempo (# antes y \n después) dentro de un sustitución de procesos
  • diff -I '^#' ignora las líneas que tienen estas marcas de tiempo (líneas que comienzan por #)

ejemplo

Dos archivos de registro que tienen el mismo contenido pero diferentes marcas de tiempo:

$> 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

Básico diff La línea de comando dice que todas las líneas son diferentes:

$> 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

nuestro complicado diff -I '^#' no muestra ninguna diferencia (se ignoran las marcas de tiempo):

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

Cambiar 2.log (reemplazar data por foo en la sexta línea) y verifique nuevamente:

$> 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

=> las marcas de tiempo se mantienen en el diff¡producción!

También puedes utilizar el lado a lado característica usando -y o --side-by-side opción:

$> 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

viejo sed

Si tu sed La implementación no apoya la -r opción, es posible que tengas que contar los doce puntos <(sed 's/^\(............\)/#\1\n/' 1.log) o usa otro patrón de tu elección ;)

Para una opción gráfica, fusionar puede hacer esto usando su filtros de texto característica.

Permite ignorar líneas basadas en una o más expresiones regulares de Python.Las diferencias siguen apareciendo, pero las líneas que no tengan otras diferencias no se resaltarán.

Example configuration

Usar kdiff3 y en Configurar>Diferencia editar "Comando de preprocesador de coincidencia de líneas" a algo como:

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

Esto filtrará las marcas de tiempo del algoritmo de alineación de comparación.

Kdiff3 también te permite alinear manualmente líneas específicas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top