Diferencia de cadena de bash


70

Estoy tratando de encontrar una manera de determinar la diferencia entre dos cadenas en mi secuencia de comandos. Podría hacer esto fácilmente con diff o comm, pero no estoy tratando con archivos y preferiría no sacarlos a los archivos, hacer la comparación y leerlos de nuevo.

Veo que comm, diff, cmp todo permite pasar dos archivos O un archivo y entrada estándar - Supongo que es bueno si no quiero dar salida a dos archivos ... pero todavía es un poco asqueroso.

He estado cavilando pensando que puedo usar grep o expresiones regulares, pero supongo que no.

Gracias de antemano,

+1

qué es lo que realmente quiere hacer? 18 ene. 092009-01-18 02:51:04

  0

Puede usar manipulaciones de subcadenas y operaciones de prueba integradas con cambios IFS para comparar, pero necesitará saber si desea comparar carácter por carácter, palabra por palabra, línea por línea, ignorar el espacio en blanco ... 21 jul. 122012-07-21 10:33:51

9

Me recuerda a esta pregunta: How can you diff two pipelines in Bash?

Si usted está en una sesión de bash, se puede hacer un:

diff <cmd1 <cmd2 
diff <(foo | bar) <(baz | quux) 

con < creación de canalizaciones con nombre anónimas - - administrado por bash - por lo que se crean y destruyen automáticamente, a diferencia de los archivos temporales.

Así que si logra aislar a su hijo de dos cuerdas diferentes como parte de un comando (grep, awk, sed, ...), se puede hacer - por ejemplo - algo así como:

diff < grep string1 myFile < grep string2 myFile 

(si que suponga que tiene en sus líneas de archivo como string1=very_complicated_value y una string2=another_long_and_complicated_value': sin conocer el formato interno de su archivo, no puedo recomendar una orden precisa)


124

Usando diff o com o como se quiera:

diff <(echo "$string1") <(echo "$string2") 

de Greg Bash FAQ: Process Substitution

o con una tubería con nombre

mkfifo ./p 
diff - p <<< "$string1" & echo "$string2" > p 

de Greg Bash FAQ: Working with Named Pipes

canalización con nombre se conoce también como una FIFO.

El - en sí mismo es para entrada estándar.

<<< es una "cadena aquí".

& es como ; sino que la pone en el fondo

+3

+1 para la respuesta correcta. +1 para una gran explicación de símbolos. Además, las preguntas frecuentes de Greg's Bash se han trasladado a: http://mywiki.wooledge.org/ Los enlaces para las páginas anteriores están ahora en http://mywiki.wooledge.org/ProcessSubstitution y http://mywiki.wooledge.org/ BashFAQ/085 20 feb. 132013-02-20 17:30:24

  0

¡gracias! y también, esto mostrará los descriptores dinámicos de archivos 'FUNC() {echo" $ @ "; ps }; FUNC diff <(echo a) <(echo b); ' 16 abr. 152015-04-16 01:30:54

  0

Estaba buscando eso para comparar dos shasums. No estoy seguro de si hay una forma más elegante de hacerlo, pero funciona. 23 ago. 162016-08-23 08:29:09

  0

Esto parece funcionar si hay varias líneas en $ string1 y $ string2, y diff genera las líneas que se agregaron o restaron. ¿Qué pasa si la cadena es una sola línea y línea y hay alguna diferencia entre las dos cadenas? 10 ago. 172017-08-10 15:28:00


11

prefiero cmp y Proceso función de sustitución de fiesta:

$ cmp -bl <(echo -n abcda) <(echo -n aqcde) 
    2 142 b 161 q 
    5 141 a 145 e 

decir en la posición 2, ab se produce por primera, pero aq para el segundo. En la posición 5, está ocurriendo otra diferencia. Simplemente reemplace esas cadenas por variables, y listo.

  0

¡Esto funciona solo cuando las cadenas tienen la misma longitud! 06 may. 162016-05-06 11:58:04


8

Digamos que tiene tres cadenas

a="this is a line" 
b="this is" 
c="a line" 

Para eliminar el prefijo b de un

echo ${a#"$b"} 

Para quitar el sufijo c de un

echo ${a%"$c"} 
+1

Supongo que esta es la forma bash de hacerlo. Funcionó bien. Sin embargo, esa sintaxis es un poco difícil de entender. 05 nov. 142014-11-05 20:39:25

  0

@MikaelRoos de acuerdo. Más fácil de leer (para mí de todos modos) sería usar sed: 'echo" $ a "| sed "s!^$ b !! g" '(Cambié el separador de sed estándar/for! en caso de que las variables que se tratan sean rutas. Además, podría usar una cadena aquí en lugar de echo:' sed ... <<< $ a'.) 08 sep. 162016-09-08 18:06:40