Solución:
Tratar
grep -f the_ids.txt huge.csv
Además, dado que sus patrones parecen ser cadenas fijas, el suministro de -F
la opción podría acelerarse grep
.
-F, --fixed-strings
Interpret PATTERN as a list of fixed strings, separated by
newlines, any of which is to be matched. (-F is specified by
POSIX.)
Usar grep -f
para esto:
grep -f the_ids.txt huge.csv > output_file
De man grep
:
-f ARCHIVO, –archivo = ARCHIVO
Obtenga patrones de ARCHIVO, uno por línea. El archivo vacío contiene cero patrones y, por lo tanto, no coincide con nada. (-f lo especifica POSIX).
Si proporciona alguna entrada de muestra, tal vez incluso podamos mejorar el grep
condiciona un poco más.
Prueba
$ cat ids
11
23
55
$ cat huge.csv
hello this is 11 but
nothing else here
and here 23
bye
$ grep -f ids huge.csv
hello this is 11 but
and here 23
grep -f filter.txt data.txt
se vuelve rebelde cuando filter.txt
es más grande que un par de miles de líneas y, por lo tanto, no es la mejor opción para tal situación. Incluso mientras usa grep -f
, debemos tener en cuenta algunas cosas:
- usar
-x
opción si es necesario hacer coincidir toda la línea en el segundo archivo - usar
-F
si el primer archivo tiene cadenas, no patrones - usar
-w
para evitar coincidencias parciales mientras no se utiliza el-x
opción
Esta publicación tiene una gran discusión sobre este tema (grep -f
en archivos grandes):
- La forma más rápida de encontrar líneas de un archivo desde otro archivo más grande en Bash
Y esta publicación habla de grep -vf
:
- grep -vf demasiado lento con archivos grandes
En resumen, la mejor forma de manejar grep -f
en archivos grandes es:
Coincidencia de toda la línea:
awk 'FNR==NR {hash[$0]; next} $0 in hash' filter.txt data.txt > matching.txt
Coincidencia de un campo en particular en el segundo archivo (usando ‘,’ delimitador y el campo 2 en este ejemplo):
awk -F, 'FNR==NR {hash[$1]; next} $2 in hash' filter.txt data.txt > matching.txt
y para grep -vf
:
Coincidencia de toda la línea:
awk 'FNR==NR {hash[$0]; next} !($0 in hash)' filter.txt data.txt > not_matching.txt
Hacer coincidir un campo en particular en el segundo archivo (usando ‘,’ delimitador y el campo 2 en este ejemplo):
awk -F, 'FNR==NR {hash[$0]; next} !($2 in hash)' filter.txt data.txt > not_matching.txt