Você digitaliza o arquivo uma vez para cada padrão. Seria muito mais rápido passar pelo arquivo apenas uma vez, especialmente porque o arquivo não cabe no cache.
Seu código de amostra, na verdade, salva apenas as correspondências do último padrão em file1
. Eu suponho que isso seja uma simplificação excessiva. Se você precisar de todas as correspondências em um único arquivo, é como se os padrões estivessem unidos ao operador “ou”.
awk '
BEGIN {
while (getline <"file1") pattern = pattern "|" $0;
pattern = substr(pattern, 2);
}
match($0, pattern) {for(i=1; i<=3; i++) {getline; print}}
' file2 > file3
Note também que isto não imprime a linha correspondente, apenas as três linhas seguintes. Se você realmente quisesse imprimir a linha correspondente antes das três linhas seguintes, você precisa de um print;
adicional antes do loop for
.
Se você realmente quisesse imprimir a linha correspondente antes das três linhas a seguir, e seu comando grep
suportasse o argumento -A
, então você deveria usar isto. Um programa especializado como o grep é geralmente mais rápido que uma linguagem interpretada como o awk. Como um bônus adicional, o comando é muito mais simples.
grep -A -E -f file1 file2 >file3
Se você descobriu que grep é mais lento, pode ser porque você encontrou um defeito do GNU grep em localidades multibyte: às vezes pode ser muito lento, mesmo quando nem o arquivo nem o padrão contiverem caracteres multibyte. Se você não estiver usando classes de caracteres para corresponder a caracteres não-ASCII (por exemplo, você não usa [[:alpha:]]
para corresponder a todas as letras Unicode), execute grep em uma localidade unibyte:
LC_ALL=C grep -A3 -E -f file1 file2 >file3
A saída do grep não é exatamente a mesma do snippet awk, porque eles se comportam de maneira diferente se o padrão for encontrado em uma das linhas sendo impressas devido a uma linha anterior. Por exemplo, se o padrão for a
e as linhas forem a1
, a2
, b
, c
, d
então grep -A3
imprime a1
, a2
, b
, c
, enquanto o snippet de awk acima imprime a2
, b
, c
e o fragmento de awk com o% adicional print
imprime a1
, a2
, b
, c
.