cat file_1
my colour is red
my rose is red
my colour is blue
my rose id blue
cat file_2
red
blue
cat output_file should be
my colour is red
my colour is blue
aquí estoy usando
cat file_2 | while read line;do cat file_1 | grep "$line" | head -1;done
aquí estoy tratando de obtener la línea superior que contiene el pattern "red" and "blue"
que está presente en elfile_2
¿Hay alguna otra forma de hacerlo as fast as possible
mientras el bucle lleva tiempo?
Respuesta1
Puede usar una while
construcción para recorrer los patrones file2
y luego usar -m 1
with grep
para detener después de la primera coincidencia en file1
:
while IFS= read -r i; do grep -Fm1 "$i" file1; done <file2
-F
trata el patrón literalmente-m 1
hacegrep
para salir después del primer partido
Los bucles de Shell generalmente no son eficientes, pero dado que la lista de patrones es pequeña, se pueden utilizar en este caso.
Alternativa más rápida, xargs
:
xargs -a file2 -n1 -P2 -I'{}' grep -Fm1 {} file1
Utilice más procesos paralelos ( -P
) para obtener más patrones.
Ejemplo:
% while IFS= read -r i; do grep -Fm1 "$i" file1; done <file2
my colour is red
my colour is blue
% xargs -a file2 -n1 -P2 -I'{}' grep -Fm1 {} file1
my colour is blue
my colour is red
Respuesta2
Para imprimir la primera línea del archivo_1 que coincide con una línea en el archivo_2:
$ awk 'FNR==NR{a[$0];next} {for (line in a) if ($0~line) {print; delete a[line]}}' file_2 file_1
my colour is red
my colour is blue
Este enfoque lee cada archivo solo una vez.
Cómo funciona
FNR==NR{a[$0];next}
Esto guarda cada línea en file_2 como una clave en una matriz asociativa
a
.for (line in a) if ($0~line) {print; delete a[line]}
Para cada línea en file_1, verificamos si coincide con una clave en la matriz
a
. Si es así, imprimimos la línea y eliminamos la clave.