Tengo un archivo grande A (que consta de correos electrónicos), una línea para cada correo. También tengo otro archivo B que contiene otro conjunto de correos.
¿Qué comando usaría para eliminar todas las direcciones que aparecen en el archivo B del archivo A.
Entonces, si el archivo A contiene:
A
B
C
y el archivo B contenía:
B
D
E
Entonces el archivo A debe quedar con:
A
C
Ahora sé que esta es una pregunta que podría haberse hecho con más frecuencia, pero solo encontré un comando en línea que me dio un error con un delimitador incorrecto.
Cualquier ayuda sería muy apreciada! Alguien seguramente obtendrá una ingeniosa frase, pero yo no soy el experto en shell.
Respuestas:
Si los archivos están ordenados (están en su ejemplo):
-23
suprime las líneas que están en ambos archivos, o solo en el archivo 2. Si los archivos no están ordenados, canalícelossort
primero ...Vea la página del manual aquí
fuente
comm -23 file1 file2 > file3
generará contenido en el archivo1 no en el archivo2, al archivo3. Y luegomv file3 file1
finalmente borraría los contenidos redundantes en el archivo1.comm -23 file1 file2 | sponge file1
. No se necesita limpieza.grep -Fvxf <lines-to-remove> <all-lines>
Ejemplo:
Salida:
Explicación:
-F
: use cadenas literales en lugar del BRE predeterminado-x
: solo considera las coincidencias que coinciden con la línea completa-v
: imprimir no coincidente-f file
: tomar patrones del archivo dadoEste método es más lento en archivos previamente ordenados que otros métodos, ya que es más general. Si la velocidad también importa, vea: Forma rápida de encontrar líneas en un archivo que no están en otro?
Aquí hay una automatización rápida de bash para la operación en línea:
GitHub aguas arriba .
uso:
Ver también: /unix/28158/is-there-a-tool-to-get-the-lines-in-one-file-that-are-not-in-another
fuente
¡Awk al rescate!
Esta solución no requiere entradas ordenadas. Primero debe proporcionar el archivo B.
devoluciones
¿Como funciona?
Tenga en cuenta que esto ahora se puede utilizar para eliminar palabras en la lista negra.
Con un ligero cambio, puede limpiar varias listas y crear versiones limpias.
fuente
A\nC
escribir primero en un archivo temporal y sobrescribir el archivo original... > tmp && mv tmp fileA
fileB
no esté vacío (0 bytes de longitud), porque si lo es, obtendrá un resultado vacío en lugar del contenido esperado defileA
. (Causa:FNR==NR
se aplicará afileA
entonces.)Otra forma de hacer lo mismo (también requiere una entrada ordenada):
En Bash, si los archivos no están ordenados previamente:
fuente
Puede hacer esto a menos que sus archivos estén ordenados
--new-line-format
es para líneas que están en el archivo b pero no en a--old-..
es para líneas que están en el archivo a pero no en b--unchanged-..
es para líneas que están en ambos.%L
hace que la línea se imprima exactamente.para más detalles
fuente
comm
comando.comm
requiere que los archivos estén ordenados, por lo que si están ordenados, también puede usar esa solución. Sin embargoEste refinamiento de la buena respuesta de @karakfa puede ser notablemente más rápido para archivos muy grandes. Al igual que con esa respuesta, ninguno de los archivos necesita ser ordenado, pero la velocidad está asegurada en virtud de las matrices asociativas de awk. Solo el archivo de búsqueda se guarda en la memoria.
Esta formulación también permite la posibilidad de que solo se use un campo particular ($ N) en el archivo de entrada en la comparación.
(Otra ventaja de este enfoque es que es fácil modificar el criterio de comparación, por ejemplo, recortar los espacios en blanco iniciales y finales).
fuente
Puedes usar Python:
fuente
Puedes usar -
diff fileA fileB | grep "^>" | cut -c3- > fileA
Esto funcionará para archivos que no están ordenados también.
fuente
Para eliminar líneas comunes entre dos archivos, puede usar el comando grep, comm o join.
Esto muestra líneas del archivo1 que no coinciden con ninguna línea del archivo2.
Esto muestra líneas del archivo1 que no coinciden con ninguna línea del archivo2.
fuente