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 possible
enquanto o loop está demorando
Responder1
Você pode usar uma while
construção para percorrer os padrões file2
e depois usar -m 1
with grep
para parar após a primeira correspondência file1
:
while IFS= read -r i; do grep -Fm1 "$i" file1; done <file2
-F
trata o padrão literalmente-m 1
fazgrep
para 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.