Excel comparando dos archivos csv y mostrando la diferencia

Estoy buscando comparar dos grandes conjuntos de archivos csv y / o un archivo csv y un archivo .txt. Creo que el archivo .txt puede necesitar ser convertido a un archivo csv solo por razones de simplicidad, pero puede o no ser necesario. O bien quiero usar excel, c ++ o python. Necesito comparar una lista de valores “aceptados” con una lista que se mide y encontrar la diferencia entre ellos si hay una. Excel puede ser la forma más fácil de hacer esto, pero Python o c ++ pueden funcionar igual de bien. Esto no es tarea, así que no te preocupes por ese tipo de cosas. Consejos de código y / o plantillas son muy apreciados. o enlaces a sitios web

EDITAR 1

He leído sobre difflib o diferentes clases de Python, pero no sé cómo usarlo y puede ser más de lo que quiero.

Editar 2

Ambos archivos tendrán una serie de columnas (no con líneas dibujadas entre ellas ni nada) y debajo de esas columnas “nombradas” habrá números. Necesito comparar el número en la columna 1 punto uno en el archivo uno a la columna 1 punto uno del archivo 2 y si hay una diferencia, muestre la diferencia en otro archivo CSV

Puede usar ADO (controlador de texto ODBC / JET / OLEDB) para tratar los archivos ‘.txt / .csv / .tab / .flr’ decentes ‘como tablas en una base de datos SQL de todos los lenguajes habilitados para COM. Luego, las comparaciones se podrían hacer usando el poder de SQL (DISTINCT, GROUP, (LEFT) JOINS, …).

Agregado con respecto a su comentario:

Es tu problema y no quiero empujarte a donde no quieres ir. Pero SQL es una buena herramienta (¿la mejor?), Si necesita comparar datos tabulares. Como evidencia, el resultado de un script que detecta las diferencias en dos archivos .txt:

======= The .txt files to play with ------- file1.txt "AC";"AM" 40000;-19083,00 40100;20000,00 40200;350004,00 40300;3498,99 ------- file2.txt "AC";"AM" 40000;-19083,00 40300;3498,99 40105;-234567,00 40200;350,00 ======= Some diagnostic SQL -------  indicates: In F1 but not in F2 (LEFT JOIN) SELECT T1.AC, T1.AM, T2.AM FROM [file1.txt] AS T1 LEFT JOIN [file2.txt] AS T2 ON (T1.AC = T2.AC) ------- Result AC File1 File2 40000 -19083 -19083 40100 20000  40200 350004 350 40300 3498,99 3498,99 -------  indicates: Not in the other file (LEFT JOIN, UNION) SELECT T1.AC, T1.AM, T2.AM FROM [file1.txt] AS T1 LEFT JOIN [file2.txt] AS T2 ON (T1.AC = T2.AC) UNION SELECT T2.AC, T1.AM, T2.AM FROM [file2.txt] AS T2 LEFT JOIN [file1.txt] AS T1 ON (T1.AC = T2.AC) ------- Result AC File1 File2 40000 -19083 -19083 40100 20000  40105  -234567 40200 350004 350 40300 3498,99 3498,99 ------- the problems: missing, different values SELECT T1.AC, T1.AM, T2.AM FROM [file1.txt] AS T1 LEFT JOIN [file2.txt] AS T2 ON (T1.AC = T2.AC) WHERE T2.AM IS NULL OR T1.AM <> T2.AM UNION SELECT T2.AC, T1.AM, T2.AM FROM [file2. txt] AS T2 LEFT JOIN [file1.txt] AS T1 ON (T1.AC = T2.AC) WHERE T1.AM IS NULL OR T1.AM <> T2.AM ------- Result AC File1 File2 40100 20000  40105  -234567 40200 350004 350 

Otras adiciones:

Este artículo trata sobre ADO y archivos de texto; busque un archivo adoNNN.chm (NNN = número de versión, por ejemplo, 210) en su computadora; Este es un buen libro sobre ADO.

Puede usar Access o OpenOffice Base para experimentar con sentencias de SQL aplicadas a una base de datos de texto vinculada / referenciada (¡no importada!).

Un script / progtwig será fácil después de dominar el obstáculo inicial: conectarse a la base de datos, es decir, a una carpeta que contenga los archivos y un archivo schema.ini para definir la estructura de las tablas de files =.

La salida anterior fue generada por:

  Const adClipString = 2 Dim oFS : Set oFS = CreateObject( "Scripting.FileSystemObject" ) Dim sDir : sDir = oFS.GetAbsolutePathName( ".\txt" ) Dim oDB : Set oDb = CreateObject( "ADODB.Connection" ) oDB.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & sDir & ";Extended Properties=""text""" Dim sSQL Dim sFiNa WScript.Echo "=======", "The .txt files to play with" For Each sFiNa In Array( "file1.txt", "file2.txt" ) WScript.Echo "-------", sFiNa WScript.Echo oFS.OpenTextFile( "txt\" & sFiNa ).ReadAll() Next WScript.Echo "=======", "Some diagnostic SQL" Dim aSQL For Each aSQL In Array( _ Array( " indicates: In F1 but not in F2 (LEFT JOIN)" _ , Join( Array( _ "SELECT T1.AC, T1.AM, T2.AM FROM" _ , "[file1.txt] AS T1" _ , "LEFT JOIN [file2.txt] AS T2 ON (T1.AC = T2.AC)" _ ), " " ) ) _ , Array( " indicates: Not in the other file (LEFT JOIN, UNION)" _ , Join( Array( _ "SELECT T1.AC, T1.AM, T2.AM FROM" _ , "[file1.txt] AS T1" _ , "LEFT JOIN [file2.txt] AS T2 ON (T1.AC = T2.AC)" _ , "UNION" _ , "SELECT T2.AC, T1.AM, T2.AM FROM" _ , "[file2.txt] AS T2" _ , "LEFT JOIN [file1.txt] AS T1 ON (T1.AC = T2.AC)" _ ), " " ) ) _ , Array( "the problems: missing, different value" _ , Join( Array( _ "SELECT T1.AC, T1.AM, T2.AM FROM" _ , "[file1.txt] AS T1" _ , "LEFT JOIN [file2.txt] AS T2 ON (T1.AC = T2.AC)" _ , "WHERE T2.AM IS NULL OR T1.AM <> T2.AM" _ , "UNION" _ , "SELECT T2.AC, T1.AM, T2.AM FROM" _ , "[file2.txt] AS T2" _ , "LEFT JOIN [file1.txt] AS T1 ON (T1.AC = T2.AC)" _ , "WHERE T1.AM IS NULL OR T1.AM <> T2.AM" _ ), " " ) ) _ ) sSQL = aSQL( 1 ) WScript.Echo "-------", aSQL( 0 ) WScript.Echo sSQL Dim oRS : Set oRS = oDB.Execute( sSQL ) WScript.Echo "------- Result" WScript.Echo Join( Array( "AC", "File1", "File2" ), vbTab ) WScript.Echo oRS.GetString( adClipString, , vbTab, vbCrLf, "" ) Next oDB.Close 

Si elimina / ignora el grueso (crear sentencias de SQL, salida de diagnóstico), se reduce a 6 líneas

  Dim oDB : Set oDb = CreateObject( "ADODB.Connection" ) oDB.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & sDir & ";Extended Properties=""text""" sSQL = "..." Dim oRS : Set oRS = oDB.Execute( sSQL ) WScript.Echo oRS.GetString( adClipString, , vbTab, vbCrLf, "" ) oDB.Close 

que puede ser “portado” fácilmente a cualquier lenguaje habilitado para COM, porque los objetos ADO hacen todo el trabajo pesado. El método .GetString es útil cuando se quiere guardar un conjunto de resultados: solo hay que dividir los argumentos separador / delimitador / nulo y volcarlo en el archivo

  oFS.CreateTextFile( ... ).WriteLine oRS.GetString( _ adClipString, , ",", vbCrLf, "" ) 

(No olvide agregar una definición para esa tabla a su schema.ini). Por supuesto, también puede usar un “SELECT / INSERT INTO”, pero tal vez no sea fácil entender o pasar el analizador de ADO Text Driver.

Cálculo de la sum:

Comience con un archivo maestro / aprobado de 5 x 2 que contenga:

 Num0 Num1 Num2 Num3 Num4 7,6 6,1 3,8 0,9 8,9 0,9 9,4 4,7 8,8 9,9 

transformarlo en expected.txt

 Num0 Num1 Num2 Num3 Num4 Spot 7,6 6,1 3,8 0,9 8,9 1 0,9 9,4 4,7 8,8 9,9 2 

añadiendo la columna Spot para que se ajuste a

 [expected.txt] ColNameHeader=True CharacterSet=1252 Format=Delimited(;) Col1=Num0 Float Col2=Num1 Float Col3=Num2 Float Col4=Num3 Float Col5=Num4 Float Col6=Spot Integer 

en su archivo schema.ini. Del mismo modo, transformar un archivo de medida como:

 Num0 Num1 Num2 Num3 Num4 7,1 1,1 3,8 0,9 8,9 0,9 9,4 4,7 8,8 9,9 

a medida.txt

 Num0 Num1 Num2 Num3 Num4 Spot 7,1 1,1 3,8 0,9 8,9 1 0,9 9,4 4,7 8,8 9,9 2 

Aplicar

  sSQL = Join( Array( _ "SELECT E.Num0 - M.Num0 AS Dif0" _ , ", E.Num1 - M.Num1 AS Dif1" _ , ", E.Num2 - M.Num2 AS Dif2" _ , ", E.Num3 - M.Num3 AS Dif3" _ , ", E.Num4 - M.Num4 AS Dif4" _ , ", E.Spot AS Spot" _ , "FROM [expected.txt] AS E" _ , "INNER JOIN [measured.txt] AS M" _ , "ON E.Spot = M.Spot" _ ), " " ) 

Escribe el conjunto de resultados para diferencias.txt

aFNames = Array (“Num0”, … “Spot”) oFS.CreateTextFile (sFSpec) .Write _ Join (aFNames, sFSep) & sRSep & oRS.GetString (adClipString,, sFSep, sRSep, “”)

y usted obtiene:

 Num0 Num1 Num2 Num3 Num4 Spot 0,5 5 0 0 0 1 0 0 0 0 0 2 

No necesita codificar, puede hacer que los separadores sean iguales en ambos archivos (espacios o comas) usando la función de reemplazo en el editor de texto y compararlo usando la herramienta de diferencias gráficas de TortoiseSVN: http://tortoisesvn.net/