Comparación de files en Unix en forma de columna

Quiero comparar dos files con el mismo número de filas y columnas con loggings en el mismo order. Solo quiero resaltar las diferencias en los valores de la columna, si hay alguno.

file A :

 1,kolkata,19,ab 2,delhi,89,cd 3,bangalore,56,ef 

file B :

 1,kolkata,21,ab 2,mumbai,89,gh 3,bangalore,11,kl 

Considerando la columna 1 como key principal, tenemos diferencias en otras columnas. Quiero resaltar esas diferencias.

El formatting de salida puede ser (no estoy seguro):

 record_number, columns_with_diff 1 3 2 2,4 3 3,4 

¿Puede diff o comm resolver mi problema? Si es así, ¿cuál sería el command exacto?

Esto sería todo. Solo un problema de estilo con la coma adicional al final de cada línea.

 awk ' BEGIN{ FS=","; ORS="" } { # read line from secondary file getline aux < "file2" split(aux,f2,",") # print current line number print NR" " # process each field in current line for(i=1; i<=NF; i++) { if ($i!=f2[i]) { print i"," } } print "\n" } ' file1 

La salida:

 1 3, 2 2,4, 3 3,4, 

Puedes hacerlo más fácil con perl :

 $ perl -F',' -anle ' BEGIN{ print "record_number, columns_with_diff"; $" = ","; } if (!defined($h{$.})) { @{$h{$.}}{0..$#F} = @F[0..$#F]; } else { @diff = grep { $h{$.}{$_} ne $F[$_] } 0..$#F; print "$.\t\t@{[map {$_+1} @diff]}"; } close ARGV if eof; ' file1 file2 record_number, columns_with_diff 1 3 2 2,4 3 3,4 

Debe eliminar las líneas en blanco en su input para este trabajo.

Explicación

  • En el bloque BEGIN , simplemente imprimimos el encabezado de salida, luego establecemos el separador de list en ,

  • @{$h{$.}}{0..$#F} = @F[0..$#F] : creamos un hash de hash con las teclas del primer hash, es el número de línea, cada sub hash tiene las keys son índice del campo less 1, y los valores son valores con los campos coresspond.

Aquí usamos una porción hash para asignar rápidamente valores al hash de hashes.

si usa Data::Dumper para imprimir el hash de hash %h , puede ver algo como esto:

 VAR1 = { '2' => { '2' => '89', '0' => '2', '1' => 'delhi', '3' => 'cd' }, '3' => { '1' => 'bangalore', '3' => 'ef', '0' => '3', '2' => '56' }, '1' => { '3' => 'ab', '1' => 'kolkata', '0' => '1', '2' => '19' } }; 
  • Si hemos creado %h ( if (!defined($h{$.})) ), Lo que significa que terminamos de procesar el file1 , simplemente comparamos cada campo de la línea actual con el valor de coresspond en %h , almacenando todo el índice que sea diferente en array @diff . map {$_+1} @diff restaura el número de columna, porque el índice de la matriz comienza en 0, el número de columna comienza en 1.

  • close ARGV if eof restre $. mostrador.