Compare dos listas de URL e imprima las URL recién agregadas a un nuevo archivo

8

Inicialmente estoy produciendo dos archivos que contienen listas de URL: me referiré a ellos como oldy new. Me gustaría comparar los dos archivos y si hay URL en el newarchivo que no están en el oldarchivo, me gustaría que se muestren en un extra_urlsarchivo.

Ahora, he leído algunas cosas sobre el uso del diffcomando, pero por lo que puedo decir, esto también analiza el orden de la información. No quiero que la orden tenga ningún efecto en la salida. Solo quiero que las URL adicionales se newimpriman en el extra_urlsarchivo, sin importar el orden en que se coloquen en cualquiera de los otros dos archivos.

¿Cómo puedo hacer esto?

neilH
fuente

Respuestas:

14

Puede usar el commcomando para comparar dos archivos y mostrar selectivamente líneas exclusivas de uno u otro, o las líneas en común. Requiere que las entradas se ordenen, pero puede ordenarlas sobre la marcha, utilizando la sustitución de procesos.

comm -13 <(sort old.txt) <(sort new.txt)

Si está utilizando una versión bashque no admite la sustitución de procesos, se puede emular utilizando canalizaciones con nombre. Un ejemplo se muestra en Wikipedia .

Barmar
fuente
Conciso pero efectivo, exactamente lo que se necesitaba, excelente código para lo que necesitaba.
neilH
Hmm, pero si la entrada está ordenada, entonces diffhará lo mismo, ¿verdad?
justhalf
diffMostrará todas las diferencias. commle permite seleccionar si desea ver las líneas del archivo 1, el archivo 2 o las que tienen en común.
Barmar
Hola Barmar, no estoy seguro de que verifiques esto, pero por si acaso, he movido este script a mi Synology Nas para ejecutarlo desde allí. Desde que ejecuté mi script desde Synology, ahora recibo el error de sintaxis: línea 60: error de sintaxis: inesperado "("
neilH
¿De qué versión bashse está ejecutando? Es posible que no admita la sustitución del proceso.
Barmar
6

Yo solo usaría grep:

grep -vFf old new > extra_urls

Explicación

  • -f: le dice grepque lea sus patrones de búsqueda de un archivo. En este caso old,.
  • -v : le dice a grep que invierta la coincidencia, que solo imprima líneas no coincidentes.
  • -F: le dice a grep que interprete sus patrones de búsqueda como cadenas, no como expresiones regulares. De esa manera, la .URL se combinará literalmente.

Combinados, estos hacen grepimprimir cualquier línea newque no estaba en old. El orden de las URL en el archivo es irrelevante.

terdon
fuente
Hola terdon, gracias por tu aporte. Acabo de probar esto y produjo un archivo de "URL extra" en blanco a pesar de que hay nuevas URL en el archivo "nuevo".
neilH
@ bms9nmh hmm, eso es extraño. Por favor, editar su pregunta para dar un ejemplo de los archivos de entrada. También es posible que desee ingresar a la sala de chat del sitio, donde podemos discutir esto más a fondo.
terdon
2
Querrás agregar -Fpatrones de texto sin formato
glenn jackman
1

Como el orden es importante para usted, use awk

awk '
    NR == FNR {old[$1]=1; next}
    !($1 in old)
' old new > extra
Glenn Jackman
fuente
1
Hola Glen, solo para aclarar, el orden no es importante. El orden de la url no es un problema, solo la diferencia entre los dos archivos, es decir, las url adicionales. No quiero la diferencia para efectuar la salida de ninguna manera.
neilH
@ bms9nmh: podrías cambiar > extraa | sort > extra. o | sort -u > extrasi solo desea que aparezca una nueva url en la salida una vez, independientemente de cuántas veces esté en la entrada. El orden de entrada puede afectar el orden de salida a menos que haga un trabajo adicional en algún lugar del camino para evitarlo.
Steve Jessop
@steve, meh, commes la mejor respuesta para esta pregunta, aunque también grep -Fvfes buena
glenn jackman
0

Tengo una aplicación llamada meld. Permite ver los dos (o tres) archivos, uno al lado del otro, muestra las diferencias y permite la copia selectiva de uno a otro o la eliminación de caracteres.

Meld se puede instalar desde un terminal con

sudo apt-get install meld 
krazykyngekorny
fuente