O comando sort tem algum suporte específico para trabalhar com enormes conjuntos de dados, porque esse é um caso de uso relativamente comum. Enormes padrões grep são um caso de uso extremamente incomum, então você não pode esperar que os desenvolvedores tenham se esforçado muito nisso.
Se a ordem das linhas não for importante, você poderá classificar os dois arquivos, após o que poderão ser comparados sem armazenar mais do que algumas linhas na memória por vez, independentemente do tamanho dos arquivos. Como o sort pode lidar com arquivos que não cabem na memória, isso é eficiente.
sort originallist >originallist.sorted
sort cleaned1 | comm -23 originallist.sorted - >cleaned2.sorted
Se a ordem original de originalistist importa, você pode adicionar números de linha a ela:
nl -w 22 originallist >originallist.numbered
# then generate cleaned1 from the numbered list
Como originallist.numbered
está classificado, você pode executar comm
para detectar linhas comuns.
Se o pedido é importante e é muito tarde para numerar as linhas, você pode tentar dividir cleaned1
em partes e fazer uma passagem em originallist
para cada bloco. Com uma divisão recente do GNU:
cp originalfile cleaned2.in
split -l 1000000 --filter='grep -Fxv -f - cleaned2.in >cleaned2.out; mv cleaned2.out cleaned2.in' cleaned1
mv cleaned2.out cleaned2
(Observe que F
não faz "correspondência de linha completa", ele faz uma correspondência de substring. Para uma correspondência de cadeia de linha completa, você precisa de -x
também.)