Existe alguma maneira mais rápida de obter esse arquivo de saída no Linux

Existe alguma maneira mais rápida de obter esse arquivo de saída no 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

aqui estou eu usando

cat file_2 | while read line;do cat file_1 | grep "$line" | head -1;done

aqui estou tentando obter a linha superior contendo o pattern "red" and "blue"que está presente nofile_2

existe alguma outra maneira de fazer, as fast as possibleenquanto o loop está demorando

Responder1

Você pode usar uma whileconstrução para percorrer os padrões file2e depois usar -m 1with greppara parar após a primeira correspondência file1:

while IFS= read -r i; do grep -Fm1 "$i" file1; done <file2
  • -Ftrata o padrão literalmente
  • -m 1faz greppara sair após a primeira partida

Os loops de shell geralmente não são eficientes, mas como a lista de padrões é pequena, é utilizável neste caso.

Alternativa mais rápida, xargs:

xargs -a file2 -n1 -P2 -I'{}' grep -Fm1 {} file1

Use mais processos paralelos ( -P) para mais padrões.

Exemplo:

% 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

Responder2

Para imprimir a primeira linha do arquivo_1 que corresponde a uma linha do arquivo_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

Essa abordagem lê cada arquivo apenas uma vez.

Como funciona

  • FNR==NR{a[$0];next}

    Isso salva cada linha em file_2 como uma chave no array associativo a.

  • for (line in a) if ($0~line) {print; delete a[line]}

    Para cada linha em file_1, verificamos se ela corresponde a uma chave em array a. Se isso acontecer, imprimimos a linha e excluímos a chave.

informação relacionada