Compare 2 archivos y elimine cualquier línea en el archivo2 cuando coincidan con los valores encontrados en el archivo1

Tengo dos archivos. estoy tratando de eliminar cualquier línea en el archivo2 cuando coinciden con los valores encontrados en el archivo1. Un archivo tiene un listado así:

Archivo 1

ZNI008 ZNI009 ZNI010 ZNI011 ZNI012 

… más de 19463 líneas

El segundo archivo incluye líneas que coinciden con los elementos enumerados en el primero: Archivo2

 copy /Y \\server\foldername\version\20050001_ZNI008_162635.xml \\server\foldername\version\folder\ copy /Y \\server\foldername\version\20050001_ZNI010_162635.xml \\server\foldername\version\folder\ copy /Y \\server\foldername\version\20050001_ZNI012_162635.xml \\server\foldername\version\folder\ copy /Y \\server\foldername\version\20050001_ZNI009_162635.xml \\server\foldername\version\folder\ 

… continúa listado hasta la línea 51360

Lo que he probado hasta ahora:

 grep -v -i -f file1.txt file2.txt > f3.txt 

no produce ninguna salida a f3.txt ni elimina ninguna línea. Lo verifiqué corriendo

 wc -l file2.txt 

y el resultado es

 51360 file2.txt 

Creo que la razón es que no hay coincidencias exactas. Cuando corro lo siguiente no muestra nada.

 comm -1 -2 file1.txt file2.txt 

Corriendo

 ( tr '\0' '\n' < file1.txt; tr '\0' '\n' < file2.txt ) | sort | uniq -c | egrep -v '^ +1' 

muestra solo una coincidencia, aunque puedo ver claramente que hay más de una coincidencia.

Alternativamente, al colocar todos los datos en un solo archivo y ejecutar lo siguiente:

 grep -Ev "$(cat file1.txt)" 1>LinesRemoved.log 

dice que el argumento tiene demasiadas líneas para procesar.

Necesito eliminar las líneas que coinciden con los elementos en el archivo1 del archivo2.

También estoy intentando esto en python: `

  #!/usr/bin/python s = set() # load each line of file1 into memory as elements of a set, 's' f1 = open("file1.txt", "r") for line in f1: s.add(line.strip()) f1.close() # open file2 and split each line on "_" separator, # second field contains the value ZNIxxx f2 = open("file2.txt", "r") for line in f2: if line[0:4] == "copy": fields = line.split("_") # check if the field exists in the set 's' if fields[1] not in s: match = line else: match = 0 else: if match: print match, line, 

`

no está funcionando bien … como estoy recibiendo ‘Traceback (última llamada más reciente): archivo “./test.py”, línea 14, en? si los campos [1] no están en s: IndexError: índice de lista fuera de rango ‘

Qué pasa:

 grep -F -v -f file1 file2 > file3 

esto está usando Bash y GNU sed debido al interruptor -i

 cp file2 file3 while read -r; do sed -i "/$REPLY/d" file3 done < file1 

Seguramente hay una mejor manera, pero aquí hay un hack- -i : D

 cp file2 file3 while read -r; do (rm file3; sed "/$REPLY/d" > file3) < file3 done < file1 

esto explota el orden de evaluación de la concha


bien, supongo que la forma correcta con esta idea es usando ed . Esto debería ser POSIX también.

 cp file2 file3 while read -r line; do ed file3 < 

En cualquier caso, grep parece ser la herramienta adecuada para el trabajo.
La respuesta de @byrondrossos debería funcionar bien para ti;)

Esto es cierto feo pero funciona. Sin embargo, la ruta debe ser la misma para todas las partes (excepto, por supuesto, la parte ZNI ###). Se eliminan todos, excepto el ### ZNI de la ruta, por lo que el comando grep -vf puede ejecutarse correctamente en los archivos ordenados.

Primero convierta “testfile2” a “testfileconverted” para mostrar solo el ZNI ###

 cat /testfile2 | sed 's:^.*_ZNI:ZNI:g' | sed 's:_.*::g' > /testfileconverted 

Segundo, use el grep inverso del archivo convertido en comparación con el “testfile1” y agregue la salida reformateada a “testfile3”

 bash -c 'grep -vf <(sort /testfileconverted) <(sort /testfile1)' | sed "s:^:\copy /Y \\\|server\\\foldername\\\version\\\20050001_:g" | sed "s:$:_162635\.xml \\\|server\\\foldername\\\version\\\folder\\\:g" | sed "s:|:\\\:g" > /testfile3 

Me gusta más la solución grep de byrondrossos, pero aquí hay otra opción:

 sed $(awk '{printf("-e /%s/d ", $1)}' file1) file2 > file3