Existe alguma maneira mais rápida de obter este arquivo de saída no linux

1
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 usando

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

aqui estou tentando obter a linha mais alta contendo o pattern "red" and "blue" que está presente no file_2

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

    
por prince 987 27.09.2016 / 06:44

2 respostas

4

Você pode usar uma construção while para fazer um loop pelos padrões de file2 e usar -m 1 com grep para parar após a primeira correspondência em file1 :

while IFS= read -r i; do grep -Fm1 "$i" file1; done <file2
  • -F trata o padrão literalmente
  • -m 1 faz grep sair depois da primeira correspondência

Os loops de shell geralmente não são eficientes, mas, considerando que a lista de padrões é pequena, é possível utilizá-lo.

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
    
por 27.09.2016 / 06:51
2

Para imprimir a primeira linha do arquivo_1 que corresponde a uma linha no 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 no arquivo_2 como uma chave na matriz associativa a .

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

    Para cada linha no arquivo_1, verificamos se ela corresponde a uma chave na matriz a . Em caso afirmativo, imprimimos a linha e excluímos a chave.

por 27.09.2016 / 06:49