Each key is unique (no duplicates), and there are an equal number of lines in each file.
Esta suposição é muito importante. Se ele for válido, este comando fará o trabalho (no Bash):
paste <(nl key.file | sort -k 2 | cut -f 1) <(sort data.file) | sort -n | cut -f 2-
Poucas ferramentas usam caracteres de tabulação como separadores. Por esse motivo, as guias não devem ocorrer em key.file
(elas podem ocorrer em data.file
). As entradas sãs em key.file
devem formar uma única coluna, portanto, isso não deve ser um problema.
Explicação:
-
nl
adiciona um número de linha na frente de cada linha dekey.file
; isso faz com que as chaves se movam para a segunda coluna;sort -k 2
ordena de acordo com a segunda coluna, ou seja, com as chaves. As chaves são então descartadas porcut -f 1
. - Outro
sort
classificadata.file
. Como as chaves na frente são exclusivas, essa classificação padrão é equivalente à classificação de acordo com as chaves exclusivas. -
Os dois resultados de
sort
-s são mesclados porpaste
. Sem o primeirocut
, uma linha de exemplo seria:4 T01F01475558 T01F01475558 30
A unicidade das chaves e o número igual delas em ambos os arquivos são cruciais. Com efeito, as mesmas chaves de ambos os
sort
-s encontram-se na mesma linha, deixandopaste
. Como você não precisa de chaves duplicadas para ocupar a memória, o primeirocut
foi usado o mais rápido possível. Com isso, a linha de exemplo real deixandopaste
é:4 T01F01475558 30
-
Essas linhas são classificadas de acordo com seu valor numérico. Os números de linha de
nl
estão na frente, portanto, esta operação introduz a ordem desejada. - No final,
cut
descarta a primeira coluna, deixando as linhas exatas dedata.file
, ainda na ordem desejada.
Como alternativa, você pode tentar isso (testado no Bash):
while IFS='' read -r ; do
[ -n "$REPLY" ] && grep "^$REPLY " data.file
done <key.file
Observe que o código espera um caractere de espaço após cada chave em data.file
.
Prós:
-
key.file
pode especificar qualquer número de chaves, chaves duplicadas, chaves inexistentes. Neste caso, não pense em "ordenar", pense em "recuperar as linhas desejadas uma por uma". - Você pode fazer stream de entrada (como stdin em vez de
key.file
, apenas omitir<key.file
) e obter a saída em tempo real.
Contras:
-
grep
interpretará as chaves como expressões regulares, isso pode sair pela culatra. Hágrep -F
, mas em geral você precisa de^
no padrão. -
read
é lento; desovagrep
novamente e novamente é lento; abrirdata.file
de novo e de novo é lento.