Compare un file antiguo y un file nuevo, pero ignore las líneas que solo existen en un file nuevo.

Tengo dos files:

  1. oldlist : contiene una list de files y un hash md5 para cada file. Esto fue generado hace un año.
  2. newlist : también contiene una list de files y un hash md5 para cada file. Sin embargo, algunos files han sido cambiados (por ejemplo, su hash md5 es diferente) y se han agregado algunos files nuevos.

Me gustaría ver todas las diferencias entre la oldlist y la list newlist , pero quiero ignorar cualquier file que no exista en la oldlist .

Es decir, no me importan los files nuevos. Solo quiero comparar los valores hash de md5 para cada file anterior, de modo que pueda ver si los files han cambiado en el último año.

He intentado con diff y comm , pero todavía no he encontrado una solución.

Use join para combinar líneas coincidentes de los dos files. Suponiendo que los nombres de file vienen después de las sums de comprobación (como en la salida md5sum ) y no contienen espacios en blanco, esto imprimirá todos los nombres de file que están presentes en ambas lists, junto con la sum de comprobación anterior y la nueva sum de comprobación:

 join -1 2 -2 2 <(sort -k 2 oldlist) <(sort -k 2 newlist) 

Para ver también files nuevos, pase la opción -a para join . Un poco de posprocesamiento de salida eliminará los nombres de file para los cuales la sum de comprobación no ha cambiado.

 join -a 2 -1 2 -2 2 <(sort -k 2 oldlist) <(sort -k 2 newlist) | awk '$2 != $3' 

Podrías hacerlo solo con awk :

 $ awk 'FNR==NR { o[$2]=$1; next } !o[$2] { print $0, "NEW"; next } $1!=o[$2] { print $0, "CHANGED" }' newlist oldlist 

(Tenga en count que el supuesto formatting de los files es el formatting de salida de md5sum : "nombre de file md5").

Actualización : explicación paso a paso de cómo funciona el awk one-liner.

 awk 'FNR==NR { # if current record number==overall record number (still processing the first file) o[$2]=$1 # store the record in array o: the key is the file name, the value is the md5 next # go to next record (do not execute the rest of the code) } # reaching this point means we are processing the second input file !o[$2] { # if array o not contains item with the current record`s file name print $0, "NEW" # print the current record and specify that it`s new next # go to next record (do not execute the rest of the code) } # reaching this point means array o contains item with the current file name $1!=o[$2] { # if the current md5 is not equal with the md5 save for the current file name print $0, "CHANGED" # print the current record and specify it`s changed }' newlist oldlist 

si entendí tu pregunta correctamente, entonces el comm puede hacer lo que quieras. Sugeriría search en comm --help

específicamente

  -1 suppress column 1 (lines unique to FILE1) -2 suppress column 2 (lines unique to FILE2) -3 suppress column 3 (lines that appear in both files) 

por lo que comm newFile oldFile -1 -3 hará lo que quieras.

Supongamos que los files se ven como (espacio separado):

 file1 md5sum1 file2 md5sum2 

Solución directa:

 # get only the files: cut -f 1 -d " " oldlist > oldlist.files # from newlist, take only files which were also in the oldlist (updated files) grep -w -F -f oldlist.files newlist > newlist.updated_files 

Y luego puedes simplemente comparar los dos files (después de la sorting):

 sort -u oldlist > oldlist.su sort -u newlist.updated_files > newlist.updated_files.su diff oldlist.su newlist.updated_files.su