Cómo comparar dos textos y archivos en PowerShell o CMD

Última actualización: 12/12/2025
Autor: Isaac
  • Compare-Object en PowerShell permite comparar archivos y colecciones de objetos, destacando diferencias e igualdades con SideIndicator.
  • Parámetros como -IncludeEqual, -ExcludeDifferent, -Property o -PassThru controlan qué se compara y cómo se presenta el resultado.
  • El comando fc.exe de CMD ofrece comparaciones en modo texto o binario, con opciones para ignorar mayúsculas, espacios o trabajar con Unicode.
  • Combinar estas herramientas con scripts, HTML y correo permite automatizar informes y detectar cambios en datos como listas de MAC o procesos.

Comparar textos en PowerShell o CMD

Cuando tienes que comparar dos textos o archivos para buscar diferencias, hacerlo a ojo es una receta perfecta para perder el tiempo y, encima, equivocarte. Si trabajas con scripts, configuraciones, logs o listados de dispositivos, disponer de una herramienta en consola que marque qué ha cambiado de una versión a otra es oro puro.

En Windows, lo más práctico es tirar de PowerShell y del símbolo del sistema (CMD), que ya vienen de serie en el sistema. Con ellos puedes enfrentar dos archivos, dos colecciones de datos o incluso resultados en memoria y ver de un vistazo qué es nuevo, qué se ha ido y qué se mantiene igual. Vamos a ver, con calma, cómo sacarles todo el jugo a Compare-Object de PowerShell y al comando fc.exe de CMD, junto con ejemplos reales y algún truco extra.

Comparar textos con PowerShell usando Compare-Object

Compare-Object es el cmdlet estándar de PowerShell para comparar dos conjuntos de objetos. En el caso más sencillo, lo utilizarás para ver diferencias entre el contenido de dos archivos de texto, pero en realidad funciona con cualquier tipo de objeto: procesos, TimeSpan, booleanos, datos CSV, resultados de scripts, etc.

La idea básica es muy simple: indicas un ReferenceObject (lo que tomas como referencia) y un DifferenceObject (lo que quieres comparar frente a la referencia). El cmdlet analiza ambos conjuntos y devuelve qué elementos aparecen solo en uno, solo en el otro o en los dos.

La sintaxis general por defecto de Compare-Object es la siguiente:

Compare-Object <PSObject[]> <PSObject[]> >]

En condiciones normales, Compare-Object intenta usar métodos de comparación propios del tipo de los objetos. Si no los encuentra, recurre al método ToString() de cada entrada y compara las cadenas resultantes. Además, puedes indicar una o varias propiedades con el parámetro -Property para que solo se comparen esos campos concretos.

El resultado incluye siempre una propiedad clave llamada SideIndicator, que marca de dónde viene cada valor: si solo está en el objeto de referencia, si solo está en el de diferencia o si se encuentra en los dos cuando pides que se muestren los iguales.

Si accidentalmente pasas $null en ReferenceObject o DifferenceObject, el cmdlet lanza un error de terminación, así que conviene asegurarse de que ambos conjuntos tienen datos antes de comparar.

Compare-Object en PowerShell

Ejemplos prácticos con Compare-Object

Para entender bien cómo funciona Compare-Object, nada mejor que ver una serie de ejemplos típicos, desde la comparación de archivos de texto hasta la de objetos complejos o el uso de parámetros como -IncludeEqual, -ExcludeDifferent o -PassThru.

Ejemplo 1: comparar el contenido de dos archivos de texto

En este escenario se tienen dos archivos de texto, cada uno con una lista de palabras en líneas separadas. Compare-Object permite ver enseguida qué elementos existen solo en un fichero y no en el otro.

Supongamos estos archivos:

  • Testfile1.txt: perro, ardilla, pájaro
  • Testfile2.txt: gato, pájaro, racoon

Un uso típico de Compare-Object sería este:

$objects = @{
ReferenceObject = Get-Content -Path C:\Test\Testfile1.txt
DifferenceObject = Get-Content -Path C:\Test\Testfile2.txt
}
Compare-Object @objects

La salida tendría este aspecto, donde InputObject refleja el valor comparado y SideIndicator indica en qué lado está:

InputObject  SideIndicator
-----------  -------------
cat        =>
racoon     =>
dog        <=
squirrel   <=

En este contexto, «=>» significa que el valor está solo en DifferenceObject (en este caso, en el contenido de Testfile2), mientras que «<=» indica que está solo en ReferenceObject (Testfile1).

Ejemplo 2: mostrar solo las líneas comunes y excluir las diferencias

Puede que lo que necesites no sea detectar qué ha cambiado, sino averiguar qué líneas son idénticas entre dos archivos. Para eso se usa la combinación de parámetros -ExcludeDifferent y -IncludeEqual, aunque a partir de PowerShell 7.1 cuando indicas ExcludeDifferent se deduce IncludeEqual.

Un ejemplo para ver solo las líneas comunes sería:

$objects = @{
ReferenceObject = Get-Content -Path C:\Test\Testfile1.txt
DifferenceObject = Get-Content -Path C:\Test\Testfile2.txt
}
Compare-Object @objects -ExcludeDifferent

El resultado es algo como:

InputObject  SideIndicator
-----------  -------------
bird        ==

Aquí se ve claramente que solo se muestra el valor «bird» con SideIndicator «==», marcando que está presente en ambos conjuntos. Si usases ExcludeDifferent sin IncludeEqual en versiones anteriores a 7.1, podrías encontrarte con que no sale nada porque se descartan tanto las diferencias como las igualdades.

Ejemplo 3: conservar el tipo original con el parámetro PassThru

Por defecto, Compare-Object devuelve objetos de tipo PSCustomObject con dos propiedades: InputObject y SideIndicator. Sin embargo, cuando quieres seguir trabajando con el tipo original (por ejemplo, un booleano, un proceso, un TimeSpan, etc.), lo que te interesa es el parámetro -PassThru.

Veamos la diferencia con un valor booleano muy sencillo:

$a = $true
Compare-Object -IncludeEqual $a $a
(Compare-Object -IncludeEqual $a $a) | Get-Member

Esto muestra una salida con TypeName System.Management.Automation.PSCustomObject y propiedades NoteProperty InputObject y SideIndicator, además de los métodos típicos de Equals, GetType, ToString, etc.

Si utilizas ahora PassThru:

Compare-Object -IncludeEqual $a $a -PassThru
(Compare-Object -IncludeEqual $a $a -PassThru) | Get-Member

En este caso, el tipo devuelto es System.Boolean, y se aprecia que la instancia tiene añadida una NoteProperty llamada SideIndicator, aunque esto no se vea de forma directa en la salida formateada en pantalla. Este detalle es importante: el tipo real es el original, pero con una propiedad extra que te indica si el valor está en referencia, en diferencia o en ambos.

Ejemplo 4: comparar cadenas simples por propiedades

Compare-Object no solo sirve para textos completos, también es útil cuando quieres comparar propiedades concretas de objetos. Por ejemplo, puedes comparar dos cadenas completamente distintas en contenido, pero que tengan la misma longitud.

Un ejemplo sería:

$objects = @{
ReferenceObject = 'abc'
DifferenceObject = 'xyz'
Property = 'Length'
}
Compare-Object @objects -IncludeEqual

El resultado:

  Methods to Set up Apps From Unknown Sources on Android

Length     SideIndicator
------    -------------
3        ==

Como se está comparando solo la propiedad Length, el cmdlet indica que ambas cadenas son equivalentes a ojos de esa propiedad, aunque su texto no tenga nada que ver.

Ejemplo 5: comparar objetos complejos con propiedades específicas

Cuando pasas a objetos más complejos, como procesos de Windows, la cosa se pone interesante. Imagina que guardas dos procesos distintos de PowerShell en variables diferentes pero comparten el mismo nombre de proceso.

Sin especificar propiedades, Compare-Object compara el resultado de ToString() de System.Diagnostics.Process, que suele ser algo como «System.Diagnostics.Process (pwsh)», y los consideran iguales.

Ejemplo resumido:

$a = Get-Process -Id 11168
$b = Get-Process -Id 17600
$a.ToString()
$b.ToString()
Compare-Object $a $b -IncludeEqual

La salida:

InputObject  SideIndicator
-----------  -------------
System.Diagnostics.Process (pwsh)  ==

Si quieres que se vean realmente las diferencias, hay que indicar propiedades concretas como ProcessName, Id o CPU:

Compare-Object $a $b -Property ProcessName, Id, CPU

En este caso obtendrás algo del estilo:

ProcessName  Id      CPU      SideIndicator
-----------  --     ---     -------------
pwsh       17600  11.4375  =>
pwsh       11168  36.203125 <=

Aquí ya se aprecia claramente qué instancia es cuál y cómo difieren en su identificador y en el tiempo de CPU consumido.

Ejemplo 6: objetos complejos que implementan IComparable

Algunos tipos .NET implementan la interfaz IComparable, lo que permite a Compare-Object compararlos de forma más inteligente. Si los objetos a comparar son de tipos distintos, el cmdlet intenta convertir DifferenceObject al tipo de ReferenceObject.

Por ejemplo, comparando una cadena que representa un TimeSpan con un propio objeto TimeSpan se dan dos casos distintos según el orden:

Compare-Object ("0:0:1") "0:0:1" -IncludeEqual

Salida:

InputObject  SideIndicator
-----------      -------------
00:00:01   ==

Aquí, la cadena se convierte en TimeSpan y ambos objetos se consideran iguales. Pero si inviertes el orden:

Compare-Object "0:0:1" ("0:0:1")

Tendrás algo como:

InputObject  SideIndicator
-----------      -------------
00:00:01   =>
0:0:1     <=

En este segundo escenario, el TimeSpan termina convirtiéndose a cadena y el resultado de la comparación considera que las representaciones son diferentes.

Parámetros importantes de Compare-Object

Compare-Object tiene un buen puñado de parámetros que conviene dominar para sacar el máximo partido. Vamos a repasar los más útiles con una explicación clara de qué hace cada uno.

Opciones de comparación en consola

Parámetro -CaseSensitive

El modificador -CaseSensitive indica que la comparación debe distinguir entre mayúsculas y minúsculas. Sin este parámetro, por defecto, PowerShell suele tratar las comparaciones de forma no sensible a mayúsculas/minúsculas en muchos contextos.

Características principales:

  • Tipo: SwitchParameter
  • Valor predeterminado: False
  • No admite comodines
  • Posición: nombrado (no posicional)

Parámetro -Culture

Con -Culture puedes especificar la referencia cultural utilizada en la comparación, algo muy útil cuando comparas cadenas que dependen del idioma, ordenación alfabética específica o reglas regionales.

Sus propiedades:

  • Tipo: String
  • Valor predeterminado: None (usa la cultura actual)
  • No acepta comodines
  • Parámetro nombrado, opcional

Parámetro -DifferenceObject

El parámetro -DifferenceObject indica el conjunto de objetos que se compara frente al conjunto de referencia. Es obligatorio en cualquier llamada que no sea puramente posicional y es donde cargas los datos nuevos, del «lado derecho».

Propiedades relevantes:

  • Tipo: PSObject[]
  • Obligatorio: True
  • Acepta entrada por canalización (pipeline): True
  • No admite comodines
  • Posición: 1 (cuando usas parámetros posicionales)

Parámetro -ExcludeDifferent

El conmutador -ExcludeDifferent sirve para ocultar las diferencias y mostrar solo las coincidencias entre referencia y diferencia. Combinado con IncludeEqual, deja la salida reducida a los valores comunes.

Aspectos clave:

  • Tipo: SwitchParameter
  • Valor predeterminado: False
  • Si se usa sin IncludeEqual en versiones antiguas, la salida puede ser vacía
  • En PowerShell 7.1+ implica automáticamente IncludeEqual

Parámetro -IncludeEqual

El parámetro -IncludeEqual habilita que se muestren también los elementos que son iguales en ambos conjuntos. Por defecto Compare-Object solo devuelve diferencias, así que este parámetro cambia por completo el tipo de información devuelta.

Detalles:

  • Tipo: SwitchParameter
  • Valor predeterminado: False
  • Al activarlo, la salida puede incluir tanto diferencias como igualdades
  • Cuando aparece «==» en SideIndicator, significa que el valor existe en ambos conjuntos

Parámetro -PassThru

Tal y como se vio antes, -PassThru indica que Compare-Object no envuelva los objetos en PSCustomObject, sino que devuelva los objetos originales, agregando únicamente la propiedad SideIndicator como NoteProperty.

Puntos clave:

  • Tipo: SwitchParameter
  • Valor predeterminado: False
  • Ideal cuando necesitas seguir manipulando el tipo real del objeto
  • La visualización en consola puede ocultar la existencia de SideIndicator si el formato por defecto del tipo no la muestra

Parámetro -Property

El modificador -Property permite definir un conjunto de propiedades específicas a comparar tanto en ReferenceObject como en DifferenceObject. En lugar de comparar el objeto completo, Compare-Object se limita a estos campos.

Características:

  • Tipo: Object[]
  • Valor predeterminado: None
  • No admite comodines en sí mismo, pero puedes usar propiedades calculadas
  • Permite propiedades calculadas, mediante bloques de script o tablas hash con la clave Expression

Parámetro -ReferenceObject

El parámetro -ReferenceObject identifica el conjunto de objetos que se toma como base en la comparación. Es la parte «antigua» o de referencia frente a la cual se compara el DifferenceObject.

Sus propiedades más importantes:

  • Tipo: PSObject[]
  • Obligatorio: True
  • No acepta entrada por canalización directa (aunque sí por nombre, según el uso)
  • No admite comodines
  • Posición: 0 si usas sintaxis posicional

Parámetro -SyncWindow

El parámetro -SyncWindow controla cuántos objetos adyacentes revisa Compare-Object al intentar resincronizar colecciones cuando no hay coincidencia en la misma posición. Es especialmente importante cuando trabajas con listas largas en las que puede haber inserciones o eliminaciones intermedias.

Propiedades:

  • Tipo: Int32
  • Valor predeterminado: ::MaxValue (es decir, recorre toda la colección)
  • Valores más pequeños pueden mejorar el rendimiento, pero reducen la precisión de la resincronización

Parámetros comunes

Compare-Object admite además los parámetros comunes de PowerShell: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction y -WarningVariable. Estos no cambian la lógica de la comparación, pero sí te permiten ajustar el comportamiento de salida, depuración y manejo de errores.

Entradas y salidas de Compare-Object

Cuando trabajas con Compare-Object conviene tener claro qué tipos de entrada admite y qué devuelve, porque de ello depende cómo encadenar el resultado con otros cmdlets o scripts.

Entradas (Inputs)

La entrada principal por canalización la recibe DifferenceObject, que acepta objetos de tipo PSObject. De esa manera puedes hacer algo como obtener datos con un cmdlet y pasarlos directamente a la comparación sin variables intermedias.

  Configurar y dominar el Explorador de Windows 11 con NVDA

Salidas (Outputs)

En cuanto a la salida, hay dos casos claramente diferenciados:

Por un lado, cuando ReferenceObject y DifferenceObject son exactamente iguales y no utilizas IncludeEqual, el cmdlet no devuelve nada. Esto es útil para usar Compare-Object en scripts que solo actúan si hay cambios.

Por otro lado, cuando se detectan diferencias, Compare-Object devuelve objetos PSCustomObject con la propiedad SideIndicator. Si además se utiliza IncludeEqual y los objetos son iguales, también se devuelven, pero con el indicador «==». Si se añade PassThru, el tipo real no cambia, pero cada instancia incorpora la NoteProperty SideIndicator, aunque la vista formateada quizá no la muestre.

Alias y notas sobre Compare-Object

En Windows, PowerShell incluye varios alias cómodos para llamar a Compare-Object de forma más corta, como compare o diff. Estos alias vienen muy bien cuando estás explorando diferencias rápidas en consola sin escribir el nombre completo del cmdlet.

Hay que tener en cuenta que, al usar PassThru, la salida que ves en la consola puede no enseñar la propiedad SideIndicator, porque el formato predeterminado de ese tipo de objeto no la incluye en la vista. Eso no significa que la propiedad no exista: puedes comprobarlo muy fácilmente usando Get-Member o seleccionando explícitamente la propiedad con Select-Object.

Ejemplo real: comparar dos listas de MAC en Excel con PowerShell

Un caso muy habitual en entornos de red es el de recibir semanalmente un listado de direcciones MAC desconocidas y tener que comprobar cuáles ya se investigaron y cuáles son nuevas. Para no volverte loco, lo mejor es mantener un archivo maestro con todas las MAC ya revisadas e ir comparando la lista nueva con ese histórico.

Imaginemos que se utilizan dos hojas de cálculo:

  • Unknown_Devices.xlsx: listado acumulado con todas las MAC conocidas y su justificación.
  • test.xlsx: listado nuevo de la semana, con una columna «Device Mac».

Una forma poco eficiente de abordar esto sería recorrer con un bucle cada MAC nueva y comprobar si aparece en el listado anterior con comparaciones sencillas tipo -ne. El problema es que comparar un valor escalar con una columna completa de un dataset de Excel no funciona como se espera, y terminas imprimiendo casi toda la lista nueva.

En lugar de eso, tiene mucho más sentido cargar ambos ficheros con Import-Excel y luego usar Compare-Object indicando la propiedad «Device Mac» para que compare solo esa columna. Algo del estilo:

$PreviousData = Import-Excel -Path 'H:\Unknown_Devices.xlsx'
$NewData = Import-Excel -Path 'C:\Users\usuario\Downloads\test.xlsx'
Compare-Object -ReferenceObject $PreviousData -DifferenceObject $NewData -Property 'Device Mac' |
Where-Object { $_.SideIndicator -eq '=>' }

Así se obtienen solo las MAC que figuran en la lista nueva y no en la antigua, que son las que hay que investigar y, una vez justificadas, añadir al archivo maestro. Si quisieras ver también las que han desaparecido, te fijarías en las que tienen SideIndicator «<=».

Generar informes HTML y logs de diferencias con PowerShell

Más allá de un simple diff textual en pantalla, PowerShell permite automatizar informes HTML y logs detallados usando Compare-Object como núcleo. Un ejemplo elaborado puede combinar:

  • Obtención de fecha actual y formato de marca de tiempo para nombrar ficheros.
  • Uso de Start-Transcript y Stop-Transcript para volcar toda la sesión a un log.
  • Definición de estilos CSS para darle formato al informe HTML (tipografías, colores, tablas, filas alternas, etc.).
  • Recorrido de máquinas o carpetas mediante tablas hash y bucles foreach.
  • Extracción de ficheros de proveedores A y B con Get-ChildItem, filtrando por fechas y extensiones distintas (txs, txt, pdf).
  • Comparación proceso a proceso con Compare-Object e interpretación del SideIndicator para marcar problemas.
  • Conversión de resultados a HTML con ConvertTo-Html y personalización de encabezados y columnas.
  • Envío por correo electrónico de los informes usando Send-MailMessage y adjuntando el HTML generado.

En ese tipo de script más complejo se suele:

Usar propiedades como InputObject y SideIndicator para construir mensajes de log del tipo «Encontrado el día X en ambas carpetas» o «Encontrada diferencia en origen/destino». Se manejan valores especiales como «0000» o «0001» para indicar que una máquina no genera ficheros.

Después se formatea el resultado con ConvertTo-Html, sustituyendo nombres de columnas mediante -replace (por ejemplo, cambiar InputObject por PROCESO y SideIndicator por ESTADO) y reemplazando los códigos «==», «=>» o «<=» por textos más legibles como «OK», «PROBLEMA PROVEEDOR-X» o «PROBLEMA PROVEEDOR-A».

Finalmente, se agrupa todo en un único HTML incluyendo títulos con <h1> y <h2>, una tabla resumen de número de máquinas y un pie con la fecha de creación, antes de enviar el informe por correo a los destinatarios deseados.

Operadores y expresiones útiles para complementar Compare-Object

En muchos scripts de comparación con PowerShell resulta vital dominar también los operadores aritméticos, lógicos, de comparación, de pertenencia y de tipo, además de utilidades como -split y -join para manipular cadenas.

A nivel aritmético, además de +, -, *, /, el operador módulo (%) devuelve el resto de una división entera. Por ejemplo, 5%3 da 2, porque 5 es 1 vez 3 y sobra 2. Estos operadores se aplican tanto a valores literales como a variables (por ejemplo, $var1 + $var2 suma el contenido de ambas si son numéricos, o concatena cadenas si son strings).

Con los operadores relacionales, PowerShell ofrece variantes sensibles y no sensibles a mayúsculas (-like / -clike, -eq / -ceq, etc.). Por ejemplo, ‘Powershell’ -like ‘*shell’ devuelve True, mientras que ‘Powershell’ -clike ‘p*shell’ da False porque en la versión «c» se distingue el caso.

Los operadores de pertenencia como -in y -contains son muy prácticos al filtrar elementos: ‘shell’ -in ‘Console’,’shell’ devuelve True, mientras que ‘Console’,’powershell’ -contains ‘shell’ da False. Cada uno se usa en sentido contrario al otro, así que puedes elegir el que encaje mejor con la lógica de tu condición.

También están los operadores de tipo, como -is, con los que puedes verificar si un valor es de un tipo dado: ‘Hola’ -is o 20 -is devuelven True, mientras que ‘B’ -is devuelve False.

En la parte lógica, tienes -and, -or y -not (o su forma abreviada !). Por ejemplo, (5 -eq 5) -and (8 -eq 9) es False porque una de las condiciones falla, mientras que (5 -eq 5) -or (8 -eq 9) es True. Y -not (8 -eq 9) también es True porque 8, evidentemente, no es igual a 9.

  Cómo iniciar sesión como administrador en Windows 11: guía completa paso a paso

Por último, operadores como -split y -join permiten descomponer y reconstruir cadenas. -split ‘PowerShell es sencillo’ devuelve los tres términos por separado, mientras que ‘Apellido:Nombre:Dirección:Fecha’ -split ‘:’ usa el carácter ‘:’ como delimitador. En sentido inverso, -join puede unir elementos de un array en una sola cadena con o sin separador.

Comparar textos y archivos con CMD usando fc.exe

Si prefieres el símbolo del sistema clásico, o te encuentras en un entorno donde solo tienes CMD, puedes recurrir a fc.exe, el comando histórico de Windows para comparar archivos. Aunque su salida es menos flexible que la de PowerShell, sigue siendo muy útil para comparaciones rápidas en modo texto o binario.

La sintaxis básica de fc es:

fc /a ] <filename1> <filename2>
fc /b <filename1> <filename2>

En modo texto (ASCII), fc compara línea a línea e intenta resincronizar los archivos al encontrar discrepancias. En modo binario, hace una comparación byte a byte sin reintentos de sincronización, y es lo que se usa por defecto para extensiones como .exe, .com, .sys, .obj, .lib o .bin.

Parámetros principales de fc.exe

Los modificadores más útiles de fc incluyen:

  • /a: abrevia la salida de una comparación ASCII, mostrando solo la primera y la última línea de cada grupo de diferencias.
  • /b: fuerza la comparación binaria byte a byte, útil para ejecutables o datos binarios.
  • /c: ignora mayúsculas y minúsculas.
  • /l: indica modo ASCII (texto), comparando línea a línea.
  • /lb<n>: fija el tamaño del búfer interno de líneas a n (por defecto 100); si hay más diferencias consecutivas, fc puede abortar con un mensaje de archivos demasiado diferentes.
  • /n: muestra los números de línea en comparaciones ASCII.
  • /off: no descarta archivos con atributo «sin conexión».
  • /t: evita convertir tabuladores a espacios; si no lo usas, las pestañas se tratan como espacios a cada octava posición.
  • /u: compara los archivos como texto Unicode.
  • /w: comprime espacios en blanco (tabuladores y espacios), tratándolos como un solo espacio y ignorando blancos al principio y final de línea.
  • /nnnn: establece cuántas líneas consecutivas deben coincidir tras una discrepancia para considerar que se ha resincronizado; el valor por defecto es 2.

Además, puedes usar caracteres comodín como * y ? en los nombres de archivo para comparar conjuntos completos. Si pones comodín en el primer archivo, fc enfrenta cada archivo especificado con el archivo o conjunto indicado en filename2; si el comodín va en filename2, fc usa el nombre correspondiente del primer conjunto.

Códigos de salida de fc.exe

Tras la ejecución, fc establece un código de salida que puedes utilizar en scripts por lotes o en automatizaciones:

  • 0: los archivos son idénticos.
  • 1: los archivos son diferentes.
  • 2: se produjo un error durante la comparación.

Ejemplos de uso de fc.exe

Para hacer una comparación ASCII abreviada de dos informes:

fc /a monthly.rpt sales.rpt

Para comparar en binario dos archivos por lotes:

fc /b profits.bat earnings.bat

Si hay diferencias, verás direcciones hexadecimales y los bytes diferentes de cada archivo. Algo del estilo:

00000002: 72 43
00000004: 65 3A
0000000E: 56 92
000005E8: 00 6E
FC: earnings.bat longer than profits.bat

Si son idénticos, el mensaje será más directo:

Comparing files profits.bat and earnings.bat
FC: no differences encountered

También puedes comparar todos los .bat del directorio actual con un archivo en concreto:

fc *.bat new.bat

O comparar archivos new.bat en distintas unidades:

fc c:new.bat d:*.bat

Y enfrentar todos los .bat de C:\ con los mismos nombres en D:\:

fc c:*.bat d:*.bat

Cuando fc hace comparaciones ASCII en archivos muy largos, utiliza un búfer interno de 100 líneas por defecto. Si encuentra más de ese número de líneas diferentes seguidas, puede devolver el mensaje «Resynch failed. Files are too different.». En comparaciones binarias de archivos enormes, fc va superponiendo bloques en memoria de manera transparente hasta terminar.

Detalles sutiles al comparar archivos de texto «idénticos»

Un caso curioso que se da a menudo es encontrarse con dos archivos de texto que parecen idénticos bajo la vista de un editor o de una herramienta de diff, pero que no se comportan igual para una aplicación concreta. Incluso al seleccionar todo en ambos, puedes ver recuentos de caracteres distintos, como 6502 frente a 6501.

Este tipo de discrepancia suele deberse a caracteres invisibles: un carácter de control, un BOM (Byte Order Mark) en codificaciones Unicode, un salto de línea extra al final del fichero, diferencias entre CRLF y LF, o un espacio en blanco que la herramienta de comparación está ignorando si está configurada para no mostrar cambios de espacio.

Cuando un software exige un formato muy específico de texto, esos detalles marcan la diferencia. Por eso es recomendable, si algo «no cuadra», comprobar la codificación del archivo, los finales de línea y usar una comparación en modo binario (con fc /b o herramientas similares) para cazar cualquier byte que esté de más o de menos.

Tanto Compare-Object en PowerShell como fc.exe en CMD proporcionan un arsenal muy potente para comparar textos, archivos y colecciones de objetos. Usándolos bien puedes detectar qué ha cambiado entre versiones, generar informes legibles en HTML, filtrar solo lo que te interesa (por ejemplo, registros nuevos en una lista de MAC) e incluso integrar esa información en procesos automáticos de monitorización o validación de datos, ahorrándote horas de revisión manual y reduciendo drásticamente los errores humanos.

Cómo comparar y combinar documentos en Word-3
Artículo relacionado:
Cómo comparar y combinar documentos en Word