GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo eliminar las líneas que aparecen en el archivo B de otro archivo A?

Si los archivos están ordenados (están en su ejemplo):

comm -23 file1 file2

-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ícelos a través de sort primero...

Ver la página man aquí


¡ay al rescate!

Esta solución no requiere entradas ordenadas. Primero debe proporcionar el archivo B.

awk 'NR==FNR{a[$0];next} !($0 in a)' fileB fileA

regresa

A
C

¿Cómo funciona?

NR==FNR{a[$0];next} modismo es para almacenar el primer archivo en una matriz asociativa como claves para una posterior prueba de "contiene".

NR==FNR está comprobando si estamos escaneando el primer archivo, donde el contador de línea global (NR) es igual al contador de línea de archivo actual (FNR).

a[$0] agrega la línea actual a la matriz asociativa como clave, tenga en cuenta que esto se comporta como un conjunto, donde no habrá valores duplicados (claves)

!($0 in a) ahora estamos en los siguientes archivos, in es una prueba de contenido, aquí está comprobando si la línea actual está en el conjunto que completamos en el primer paso del primer archivo, ! niega la condición. Lo que falta aquí es la acción, que por defecto es {print} y por lo general no se escribe explícitamente.

Tenga en cuenta que esto ahora se puede usar para eliminar palabras de la lista negra.

$ awk '...' badwords allwords > goodwords

con un ligero cambio, puede limpiar múltiples listas y crear versiones limpias.

$ awk 'NR==FNR{a[$0];next} !($0 in a){print > FILENAME".clean"}' bad file1 file2 file3 ...

Otra forma de hacer lo mismo (también requiere entrada ordenada):

join -v 1 fileA fileB

En Bash, si los archivos no están ordenados previamente:

join -v 1 <(sort fileA) <(sort fileB)

grep -Fvxf <lines-to-remove> <all-lines>

  • funciona en archivos no ordenados (a diferencia de comm )
  • mantiene el orden
  • es POSIX

Ejemplo:

cat <<EOF > A
b
1
a
0
01
b
1
EOF

cat <<EOF > B
0
1
EOF

grep -Fvxf B A

Salida:

b
a
01
b

Explicación:

  • -F :use cadenas literales en lugar del BRE predeterminado
  • -x :solo considere coincidencias que coincidan con la línea completa
  • -v :imprimir no coincidentes
  • -f file :toma patrones del archivo dado

Este método es más lento en archivos preordenados que otros métodos, ya que es más general. Si la velocidad también es importante, consulte:¿Forma rápida de encontrar líneas en un archivo que no están en otro?

Aquí hay una automatización bash rápida para la operación en línea:

remove-lines() (
  remove_lines="$1"
  all_lines="$2"
  tmp_file="$(mktemp)"
  grep -Fvxf "$remove_lines" "$all_lines" > "$tmp_file"
  mv "$tmp_file" "$all_lines"
)

GitHub ascendente.

uso:

remove-lines lines-to-remove remove-from-this-file

Consulte también:https://unix.stackexchange.com/questions/28158/is-there-a-tool-to-get-the-lines-in-one-file-that-are-not-in-another


Linux
  1. ¿Cómo quitar el Bom de un archivo Utf-8?

  2. ¿Cómo elimino archivos de la papelera en Ubuntu?

  3. ¿Cómo elimino líneas nuevas de un archivo de texto?

  4. ¿Cómo uso las líneas de un archivo como argumentos de un comando?

  5. ¿Cómo eliminar X bytes del final de un archivo grande sin leer todo el archivo?

Cómo quitar la contraseña de un archivo PDF en Linux

Cómo descomprimir los archivos gz en Linux

Cómo quitar líneas de un archivo usando el comando Sed

Cómo quitar (^M) caracteres de un archivo en Linux

Cómo eliminar archivos enumerados en otro archivo en Linux

¿Cómo copiar un archivo de otro directorio al actual?