¿Existe alguna forma más rápida de obtener este archivo de salida en Linux?

¿Existe alguna forma más rápida de obtener este archivo de salida en Linux?
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 possiblemientras el bucle lleva tiempo?

Respuesta1

Puede usar una whileconstrucción para recorrer los patrones file2y luego usar -m 1with greppara detener después de la primera coincidencia en file1:

while IFS= read -r i; do grep -Fm1 "$i" file1; done <file2
  • -Ftrata el patrón literalmente
  • -m 1hace greppara 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.

información relacionada