it-swarm-es.com

¿Cómo difiero dos archivos de texto en Windows Powershell?

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                                                     <=
104
Brian Willis

Lo descubrí yo mismo. Debido a que Powershell funciona con objetos .net en lugar de texto, debe usar get-content para exponer el contenido de los archivos de texto. Entonces, para realizar lo que estaba tratando de hacer en la pregunta, use:

compare-object (get-content one.txt) (get-content two.txt)
110
Brian Willis

Una forma más sencilla de hacerlo es escribir:

diff (cat file1) (cat file2)
34
Alex Y.

O puede usar el comando DOS fc así (Esto muestra el resultado de ambos archivos, por lo que tendrá que buscar las diferencias):

fc.exe filea.txt fileb.txt > diff.txt

fc es un alias para el cmdlet Format-Custom, así que asegúrese de ingresar el comando como fc.exe. Tenga en cuenta que muchas utilidades de DOS no manejan la codificación UTF-8.

También puede generar un proceso CMD y ejecutar fc dentro de él.

start cmd "/c  ""fc filea.txt fileb.txt >diff.txt"""

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 '/ c' cmd para ejecutar el comando y finalizar. El comando real para ejecutar por cmd en el proceso es fc filea.txt fileb.txt redirigiendo la salida al archivo diff.txt.

Puedes usar el DOS fc.exe desde dentro de powershell.

32
phord350

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/ )

7
Mikeage

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.

4
Marc Towersap

Como otros han notado, si esperaba una salida unix-y diff, el uso del alias powershell diff lo decepcionaría mucho. Por un lado, debes tener en cuenta la lectura de los 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 sana

  1. obtener una diferencia real (por ejemplo, de GnuWin32)
  2. editar% USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
  3. agrega la línea

    remove-item alias:diff -force
    

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:

remove-item alias:rm
remove-item alias:mv
remove-item alias:cp

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í.

3
daf

WinMerge es otra buena herramienta de diferencias basada en GUI.

2
Andy White

fc.exe Es mejor para comparar 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 los 0 MSB de 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, 256 bytes Unicode) por lo que las líneas largas se dividen y comparan por separado.

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 se intente volver a sincronizar, 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 una compensación 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: 1 (algunos cambios en las líneas entre archivos pero sin duplicaciones dentro de un archivo, como una lista de texto de registros de bases de datos que tienen un campo clave) luego, agregando información a cada línea que indique en qué archivo se encuentra, su posición dentro de ese archivo e ignorando la información agregada durante la comparación (pero incluyéndola en la salida) puede obtener una salida similar a * nix diff de la siguiente manera (abreviaturas de alias utilizadas ):

diff (gc file1 | % -begin { $ln1=0 } -process { '{0,6}<<:{1}' -f ++$ln1,$_ }) (gc file2 | % -begin { $ln2=0 } -process { '{0,6}>>:{1}' -f ++$ln2,$_ }) -property { $_.substring(9) } -passthru | sort | out-string -width xx

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 parámetro $_.substring (3 más que el ancho del número de línea) y el valor xx de la cadena externa (longitud máxima de línea + parámetro $_.substring).

1
codemaster bob

También hay Windiff que proporciona una interfaz GUI diff (ideal para usar con programas CVS/SVN basados ​​en GUI)

1
saschabeaumont