Tengo dos archivos de texto y quiero encontrar las diferencias entre ellos usando Windows Powershell. ¿Hay algo similar a la herramienta Unix diff disponible? ¿O hay otra forma que no he considerado?
Intenté comparar objetos, pero obtuve esta salida críptica:
PS C:\> compare-object one.txt two.txt
InputObject SideIndicator
----------- -------------
two.txt =>
one.txt <=
windows
powershell
Brian Willis
fuente
fuente
-SyncWindow 0
solucionarlo, aunque no estoy seguro si se ha introducido recientemente. Sin embargo, no es particularmente inteligente al respecto.Una forma más sencilla de hacerlo es escribir:
fuente
diff
en absoluto, como lo señalan otras respuestas aquí. Y cuando utilicé una expresión más compleja en lugar decat
, obtuve un resultado incorrecto, por lo que me uniré a los demás en la recomendación para evitar hacer esto en PowerShell si vienes de * nix.O puede usar el
fc
comando DOS de esta manera (Esto muestra el resultado de ambos archivos, por lo que tendrá que buscar las diferencias):fc
es un alias para el cmdlet Format-Custom, así que asegúrese de ingresar el comando comofc.exe
. Tenga en cuenta que muchas utilidades de DOS no manejan la codificación UTF-8.También puede generar un proceso CMD y ejecutarlo
fc
.Esto le indica a PowerShell que inicie un proceso con el programa 'cmd' usando los parámetros entre comillas. En las comillas, es la opción cmd '/ c' para ejecutar el comando y finalizar. El comando real que debe ejecutar cmd en el proceso es
fc filea.txt fileb.txt
redirigir la salida al archivodiff.txt
.Puede usar el DOS
fc.exe
desde powershell.fuente
diff on * nix no es parte del shell, sino una aplicación separada.
¿Hay alguna razón por la que no pueda usar diff.exe en PowerShell?
Puede descargar una versión del paquete UnxUtils ( http://unxutils.sourceforge.net/ )
fuente
git diff
, porque ya lo tenía instalado. Nifc.exe
produjeCompare-Object
la salida que esperaba.compare-object (también conocido como diff alias) es patético si espera que se comporte como un unix diff. Probé el diff (gc file1) (gc file2), y si una línea es demasiado larga, no puedo ver el diff real y, lo que es más importante, no puedo decir en qué número de línea está el diff.
Cuando trato de agregar -passthru, ahora puedo ver la diferencia, pero pierdo en qué archivo está la diferencia y aún no obtengo un número de línea.
Mi consejo, no use powershell para encontrar diferencias en los archivos. Como alguien más notó, fc funciona, y funciona un poco mejor que compare-object, y aún mejor es descargar y usar herramientas reales como el emulador de Unix que mencionó Mikeage.
fuente
-SyncWindow
maxint por defecto. Establecer eso en 0 tampoco lo hace funcionar comodiff
... Y cuando pasé una tubería(... | select-object ...)
como entrada, simplemente imprimió tonterías, así que me di por vencido.Como otros han señalado, si esperaba una salida unix-y diff, el uso del alias powershell diff lo decepcionaría mucho. Por un lado, debe tener la mano en la lectura de archivos (con gc / get-content). Por otro lado, el indicador de diferencia está a la derecha, lejos del contenido: es una pesadilla de legibilidad.
La solución para cualquiera que busque una salida sensata es
agrega la línea
Se requiere el argumento -force porque Powershell es bastante valioso sobre este alias incorporado en particular. Si alguien está interesado y tiene instalado GnuWin32, también incluyo lo siguiente en mi perfil de PowerShell:
Principalmente porque Powershell no entiende los argumentos que se ejecutan juntos y escribir, por ejemplo "rm -Force -Recurse" es mucho más esfuerzo que "rm -rf".
Powershell tiene algunas características agradables, pero hay algunas cosas que simplemente no debería intentar hacer por mí.
fuente
WinMerge es otra buena herramienta de diferencias basada en GUI.
fuente
También está Windiff, que proporciona una interfaz GUI diff (ideal para usar con programas CVS / SVN basados en GUI)
fuente
fc.exe
es mejor para la comparación de texto, ya que está diseñado para funcionar como * nix diff, es decir, compara líneas secuencialmente, muestra las diferencias reales y trata de volver a sincronizar (si las secciones diferentes tienen longitudes diferentes). También tiene algunas opciones de control útiles (texto / binario, mayúsculas y minúsculas, números de línea, longitud de resincronización, tamaño de búfer no coincidente) y proporciona el estado de salida (-1 sintaxis incorrecta, 0 archivos iguales, 1 archivo diferente, faltan 2 archivos). Al ser una (muy) antigua utilidad de DOS, tiene algunas limitaciones. En particular, no funciona automáticamente con Unicode, tratando el 0 MSB de caracteres ASCII como un terminador de línea, por lo que el archivo se convierte en una secuencia de líneas de 1 carácter (@kennycoc: use la opción / U para especificar AMBOS archivos son Unicode, WinXP en adelante ) y también tiene un tamaño de búfer de línea dura de 128 caracteres (128 bytes ASCII,compare-object está diseñado para determinar si 2 objetos son idénticos en cuanto a miembros. si los objetos son colecciones, entonces se tratan como SETS (consulte la ayuda para comparar objetos), es decir, colecciones SIN ORDENAR sin duplicados. 2 conjuntos son iguales si tienen los mismos elementos miembros independientemente del orden o las duplicaciones. Esto limita severamente su utilidad para comparar archivos de texto en busca de diferencias. En primer lugar, el comportamiento predeterminado recopila las diferencias hasta que se haya verificado todo el objeto (archivo = matriz de cadenas), perdiendo así la información sobre la posición de las diferencias y ocultando qué diferencias están emparejadas (y no hay un concepto de número de línea para un SET de cuerdas). El uso de -synchwindow 0 hará que se emitan las diferencias a medida que ocurren, pero evita que intente volver a sincronizarse, por lo que si un archivo tiene una línea adicional, las comparaciones de líneas posteriores pueden fallar aunque los archivos sean idénticos (hasta que haya un compensatorio línea adicional en el otro archivo, realineando las líneas coincidentes). Sin embargo, powershell es extremadamente versátil y se puede realizar una comparación de archivos útil utilizando esta funcionalidad, aunque a costa de una complejidad sustancial y con algunas restricciones sobre el contenido de los archivos. Si necesita comparar archivos de texto con líneas largas (> 127 caracteres) y donde las líneas coinciden principalmente con 1:
donde xx es la longitud de la línea más larga + 9
Explicación
(gc file | % -begin { $ln=0 } -process { '{0,6}<<:{1}' -f ++$ln,$_ })
obtiene el contenido del archivo y antepone el número de línea y el indicador de archivo (<< o >>) a cada línea (usando el operador de cadena de formato) antes de pasarlo a diff.-property { $_.substring(9) }
le dice a diff que compare cada par de objetos (cadenas) ignorando los primeros 9 caracteres (que son el número de línea y el indicador de archivo). Esto utiliza la capacidad de especificar una propiedad calculada (el valor de un bloque de script) en lugar del nombre de una propiedad.-passthru
hace que diff muestre los diferentes objetos de entrada (que incluyen el número de línea y el indicador de archivo) en lugar de los diferentes objetos comparados (que no lo hacen).sort-object
luego vuelve a poner todas las líneas en secuencia.out-string detiene el truncamiento predeterminado de la salida para que se ajuste al ancho de la pantalla (como señaló Marc Towersap) al especificar un ancho lo suficientemente grande como para evitar el truncamiento. Normalmente, esta salida se colocaría en un archivo que luego se verá utilizando un editor de desplazamiento (por ejemplo, el bloc de notas).
Nota
El formato de número de línea {0,6} proporciona un número de línea de 6 caracteres justificado a la derecha y con espacio (para ordenar). Si los archivos tienen más de 999,999 líneas, simplemente cambie el formato para que sea más ancho. Esto también requiere alterar el
$_.substring
parámetro (3 más que el ancho del número de línea) y el valor xx de la cadena (longitud máxima de línea +$_.substring
parámetro).fuente