Use una lista de palabras para grep en otra lista

8

Tengo una lista con 250 líneas. Tengo que ejecutarlos todos a través de un servidor web para obtener una lista de resultados. Sin embargo, esta lista devuelve muchas más líneas de las que me interesan. Digamos que mi list.txtes:

a.1
b.1
etc

entonces la salida es output.txt:

a.1 a b c
a.2 b a b
a.3 d k o
b.1 b o p
b.2 o i y
b.3 p i y
etc

¿Es posible utilizar el comando grep para buscar todas las palabras en list.txt en output.txt y luego generar la lista "deseada" wanted.txt? Necesito toda la línea en mi output.txt Soy nuevo en secuencias de comandos, pero lo que me gustaría es algo como

grep list.txt output.txt > wanted.txt

No he podido encontrar ningún ejemplo de esto

Ditte
fuente
¿Están ambos en orden alfabético como sus ejemplos?
Oli
No, tengo un orden no alfabético específico en mi list.txt, pero output.txt es alfabético, pero me gustaría que solo contenga los "hits" para mi list.txt en el mismo orden no alfabético
Ditte

Respuestas:

11

Ignoraría greppor este. Es bueno para las expresiones regulares, pero no parece que realmente necesites eso aquí. commpuede comparar dos archivos y mostrarle intersecciones. Usando tus ejemplos exactos:

$ comm -12 list.txt output.txt 
a.1
b.1
etc

Esto es más rápido que cualquier grep, pero depende (en gran medida) de los archivos que se ordenan. Si no lo están, puede ordenarlos previamente, pero eso alterará la salida, por lo que también se ordenará.

comm -12 <(sort list.txt) <(sort output.txt) 

Alternativamente, esta respuesta de iiSeymour te permitirá hacerlo grep. Las banderas solicitan un archivo de entrada y fuerzan una búsqueda de cadena completa y palabra completa. Esto no dependerá del pedido, sino que se basará en el output.txtpedido. Invierta los archivos si los quiere en el orden de la lista.txt.

$ grep -wFf list.txt output.txt 
a.1
b.1
etc

Si tu list.txtes realmente grande, es posible que debas abordar esto un poco más iterativamente y pasar cada línea a grep por separado. Esto aumentará masivamente el tiempo de procesamiento. En lo anterior estarías leyendo output.txtuna vez, pero de esta manera lo leerías y procesarías para cada línea list.txt. Es horrible ... Pero podría ser tu única opción. Por el lado positivo, ordena las cosas por list.txtorden.

$ while read line; do grep -wF "$line" output.txt; done < list.txt
a.1
b.1
etc
Oli
fuente
1
¡Eso es realmente inteligente! ¿Cuál es la razón del -12?
Ditte
3
-1suprime líneas exclusivas del primer archivo, -2suprime líneas exclusivas del segundo archivo y -3suprime líneas comunes a ambos. Para obtener solo las líneas comunes, suprimimos los únicos, por lo tanto -12.
Oli
¡bonito! Creo que usaré el comando comm. Y luego, cuando quiera ordenar el output.txt para que tenga el mismo orden que list.txt, ¿solo usaré el comm -12 <(sort list.txt) <(sort output.txt) después?
Ditte
El comando comm no me dio la línea completa en el resultado.txt (y lo necesito todo para obtener la información desde allí). Pero si pruebo el comando grep, me muestra grep: sin memoria. ¿Eso significa que es demasiado grande?
Ditte
el segundo ejemplo tiene una redirección STDIN redundante que el shell marcaría como un error. ya sea hacer archivos temporales o usar un fd adicional con un tipo de fondo canalizado a él (complicado en la mayoría de los shells) ... esta es más una pregunta de programación que se hace mejor en Stack Overflow . personalmente, estaría haciendo esto en python.
Skaperen