Básicamente, lo que quiero hacer es comparar dos archivos por línea por columna 2. ¿Cómo podría lograr esto?
Archivo_1.txt:
User1 US
User2 US
User3 US
Archivo_2.txt:
User1 US
User2 US
User3 NG
Archivo de salida:
User3 has changed
command-line
text-processing
Roboman1723
fuente
fuente
diff "File_1.txt" "File_2.txt"
Respuestas:
Mira el
diff
comando. Es una buena herramienta, y puede leer todo al escribirman diff
en su terminal.El comando que querrás hacer es el
diff File_1.txt File_2.txt
que generará la diferencia entre los dos y debería verse así:Una nota rápida sobre la lectura del resultado del tercer comando: las 'flechas' (
<
y>
) se refieren a cuál es el valor de la línea en el archivo izquierdo (<
) frente al archivo derecho (>
), siendo el archivo izquierdo el que ingresó primero en la línea de comando, en este casoFile_1.txt
Además, es posible que observe que el cuarto comando es que
diff ... | tee Output_File
canaliza los resultados dediff
atee
, que luego coloca esa salida en un archivo, para que pueda guardarlo para más adelante si no desea verlo todo en la consola en ese momento.fuente
diff file1 file2 -s
. Aquí hay un ejemplo: imgur.com/ShrQx9xO puedes usar Meld Diff
Instalar ejecutando:
Su ejemplo:
Comparar directorio:
Ejemplo con texto completo:
fuente
Puedes usar vimdiff .
Ejemplo:
fuente
dos
y el segundo enunix
.FWIW, me gusta bastante lo que obtengo con la salida de lado a lado de diff
daría algo como:
fuente
Puedes usar el comando
cmp
:la salida sería
fuente
cmp
es mucho más rápido quediff
si todo lo que quieres es el código de retorno.Meld
Es una herramienta realmente genial. Pero también puede usardiffuse
para comparar visualmente dos archivos:fuente
Literalmente apegado a la pregunta (archivo1, archivo2, archivo de salida con el mensaje "ha cambiado") el script a continuación funciona.
Copie el script en un archivo vacío, guárdelo como
compare.py
, hágalo ejecutable, ejecútelo con el comando:La secuencia de comandos:
Con unas pocas líneas adicionales, puede hacer que se imprima en un archivo de salida o en el terminal, dependiendo de si el archivo de salida está definido:
Para imprimir en un archivo:
Para imprimir en la ventana de terminal:
La secuencia de comandos:
fuente
Una manera fácil es usarla
colordiff
, que se comporta comodiff
pero colorea su salida. Esto es muy útil para leer diferencias. Usando tu ejemplo,donde la
u
opción da una diferencia unificada. Así es como se ve la diferencia coloreada:Instalar
colordiff
ejecutandosudo apt-get install colordiff
.fuente
Respuesta adicional
Si no hay necesidad de saber qué partes de los archivos difieren, puede usar la suma de comprobación del archivo. Hay muchas formas de hacerlo, usando
md5sum
osha256sum
. Básicamente, cada uno de ellos genera una cadena en la que un archivo contiene hash. Si los dos archivos son iguales, su hash también será el mismo. Esto se usa a menudo cuando descarga software, como imágenes iso de instalación de Ubuntu. A menudo se usan para verificar la integridad de un contenido descargado.Considere la secuencia de comandos a continuación, donde puede dar dos archivos como argumentos, y el archivo le dirá si son iguales o no.
Ejecución de muestra:
Respuesta anterior
Además, hay un
comm
comando, que compara dos archivos ordenados, y da salida en 3 columnas: columna 1 para elementos únicos para el archivo # 1, columna 2 para elementos únicos para el archivo # 2 y columna 3 para elementos presentes en ambos archivos.Para suprimir cualquiera de las columnas, puede usar los modificadores -1, -2 y -3. El uso de -3 mostrará las líneas que difieren.
A continuación puede ver la captura de pantalla del comando en acción.
Solo hay un requisito: los archivos deben ordenarse para que se puedan comparar correctamente.
sort
El comando se puede utilizar para ese propósito. A continuación se muestra otra captura de pantalla, donde los archivos se ordenan y luego se comparan. Las líneas que comienzan en la campana izquierda son solo para File_1, las líneas que comienzan en la columna 2 pertenecen solo a File_2fuente
Instalar git y usar
Y obtendrá la salida en un bonito formato de color
Instalación de Git
fuente
colcmp.sh
Compara pares de nombre / valor en 2 archivos en el formato
name value\n
. Escribe elname
paraOutput_file
si ha cambiado. Requiere bash v4 + para matrices asociativas .Uso
Archivo de salida
Fuente (colcmp.sh)
Explicación
Desglose del código y lo que significa, a mi entender. Agradezco las ediciones y sugerencias.
Comparación de archivos básicos
cmp establecerá el valor de $? como sigue :
Decidí usar un caso ... esa declaración para evaluar $? porque el valor de $? cambia después de cada comando, incluida la prueba ([).
Alternativamente, ¿podría haber usado una variable para mantener el valor de $? :
Arriba hace lo mismo que la declaración del caso. IDK que me gusta más.
Borrar la salida
Arriba borra el archivo de salida, por lo que si ningún usuario ha cambiado, el archivo de salida estará vacío.
Hago esto dentro de las declaraciones de caso para que el Output_file permanezca sin cambios en caso de error.
Copiar archivo de usuario a la secuencia de comandos de Shell
Arriba copia File_1.txt al directorio de inicio del usuario actual.
Por ejemplo, si el usuario actual es john, lo anterior sería lo mismo que cp "File_1.txt" /home/john/.colcmp.arrays.tmp.sh
Escapar de personajes especiales
Básicamente, soy paranoico. Sé que estos caracteres podrían tener un significado especial o ejecutar un programa externo cuando se ejecutan en un script como parte de la asignación de variables:
Lo que no sé es cuánto no sé sobre bash. No sé qué otros personajes podrían tener un significado especial, pero quiero escapar de todos con una barra invertida:
sed puede hacer mucho más que la coincidencia de patrones de expresión regular . El patrón de script "s / (find) / (replace) /" realiza específicamente la coincidencia del patrón.
"s / (buscar) / (reemplazar) / (modificadores)"
en inglés: capturar cualquier puntuación o carácter especial como caputure group 1 (\\ 1)
en inglés: prefija todos los caracteres especiales con una barra invertida
en inglés: si se encuentra más de una coincidencia en la misma línea, reemplácelas todas
Comente el guión completo
El anterior usa una expresión regular para prefijar cada línea de ~ / .colcmp.arrays.tmp.sh con un carácter de comentario bash ( # ). Hago esto porque más tarde tengo la intención de ejecutar ~ / .colcmp.arrays.tmp.sh usando el comando de origen y porque no sé con seguridad el formato completo de File_1.txt .
No quiero ejecutar accidentalmente código arbitrario. No creo que nadie lo haga.
"s / (buscar) / (reemplazar) /"
en inglés: captura cada línea como caputure group 1 (\\ 1)
en inglés: reemplace cada línea con un símbolo de libra seguido de la línea que fue reemplazada
Convertir valor de usuario a A1 [Usuario] = "valor"
Arriba está el núcleo de este script.
#User1 US
A1[User1]="US"
A2[User1]="US"
(para el segundo archivo)"s / (buscar) / (reemplazar) /"
en inglés:
captura el resto de la línea como grupo de captura 2
(reemplazar) = A1 \\ [\\ 1 \\] = \ "\\ 2 \"
A1[
para iniciar la asignación de matriz en una matriz llamadaA1
]="
]
= asignación de matriz cerrada, por ejemplo,A1[
Usuario1]="
US"
=
= operador de asignación, por ejemplo, variable = valor"
= valor de cotización para capturar espacios ... aunque ahora que lo pienso, hubiera sido más fácil dejar que el código anterior reduzca todo a los caracteres de espacio.en inglés: reemplace cada línea en el formato
#name value
con un operador de asignación de matriz en el formatoA1[name]="value"
Hacer ejecutable
El anterior usa chmod para hacer que el archivo de script de matriz sea ejecutable.
No estoy seguro si esto es necesario.
Declarar matriz asociativa (bash v4 +)
La A mayúscula indica que las variables declaradas serán matrices asociativas .
Es por eso que el script requiere bash v4 o superior.
Ejecute nuestro script de asignación variable de matriz
Ya lo tenemos:
User value
a líneas deA1[User]="value"
,Por encima de que la fuente de la secuencia de comandos para ejecutar en el shell actual. Hacemos esto para poder mantener los valores variables que establece el script. Si ejecuta el script directamente, genera un nuevo shell, y los valores de las variables se pierden cuando el nuevo shell sale, o al menos eso entiendo.
Esto debería ser una función
Hacemos lo mismo por $ 1 y A1 que por $ 2 y A2 . Realmente debería ser una función. Creo que en este momento este script es lo suficientemente confuso y funciona, así que no lo arreglaré.
Detectar usuarios eliminados
Bucles anteriores a través de claves de matriz asociativas
Lo anterior utiliza la sustitución de variables para detectar la diferencia entre un valor no establecido frente a una variable que se ha establecido explícitamente en una cadena de longitud cero.
Aparentemente, hay muchas maneras de ver si se ha establecido una variable . Elegí el que tenía más votos.
Arriba agrega el usuario $ i al Output_File
Detectar usuarios agregados o modificados
Arriba borra una variable para que podamos hacer un seguimiento de los usuarios que no cambiaron.
Bucles anteriores a través de claves de matriz asociativas
El anterior usa la sustitución de variables para ver si se ha establecido una variable .
Como $ i es la clave de matriz (nombre de usuario) $ A2 [$ i] debería devolver el valor asociado con el usuario actual de File_2.txt .
Por ejemplo, si $ i es Usuario1 , lo anterior se lee como $ {A2 [Usuario1]}
Arriba agrega el usuario $ i al Output_File
Como $ i es la clave de matriz (nombre de usuario) $ A1 [$ i] debería devolver el valor asociado con el usuario actual de File_1.txt , y $ A2 [$ i] debería devolver el valor de File_2.txt .
Arriba compara los valores asociados para el usuario $ i de ambos archivos.
Arriba agrega el usuario $ i al Output_File
Arriba crea una lista separada por comas de usuarios que no cambiaron. Tenga en cuenta que no hay espacios en la lista, de lo contrario, se deberá citar la siguiente comprobación.
Arriba se informa el valor de $ USERSWHODIDNOTCHANGE pero solo si hay un valor en $ USERSWHODIDNOTCHANGE . La forma en que esto está escrito, $ USERSWHODIDNOTCHANGE no puede contener espacios. Si necesita espacios, lo anterior podría reescribirse de la siguiente manera:
fuente