Processamento de Dados Grande: Removendo linhas em um documento de texto encontrado em outro

1

Eu tenho 2 arquivos de texto grandes (~ 500M, ~ 15GB ea) que se parecem com isso:

FileP.txt:

[email protected]:testtest 
[email protected]:testtest1
[email protected]:testtest2
[email protected]:testtest3
[email protected]:testtest4

FileE.txt

[email protected]:testtest
[email protected]:testtest0
[email protected]:testtest2
[email protected]:testtest3
[email protected]:testtest5

(Observe como FileE.txt tem linhas que não estão em FileP.txt . Não quero as incluídas. Linhas em negrito são linhas que devem terminar em output.txt , pois não estão em FileE.txt .)

Eu quero executar FileE.txt contra FileP.txt e remover todas as linhas encontradas em FileE.txt de FileP.txt e enviá-las para um novo arquivo.

Deveria ser assim:

Output.txt:

[email protected]:testtest1
[email protected]:testtest4

Eu tentei alguns comandos,

Aqui está o meu comando grep:

$ grep -Fvxf FileE.txt FileP.txt > output.txt

No entanto, recebo este erro (Obviamente, porque os arquivos são muito grandes):

grep: memory exhausted

Para os interessados, executando $ ulimit -a returns:

core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 8
stack size              (kbytes, -s) 2032
cpu time               (seconds, -t) unlimited
max user processes              (-u) 256
virtual memory          (kbytes, -v) unlimited

Então, minha pergunta é: qual seria o mais eficiente & maneira mais fácil de concluir este processo?

NOTA: Os arquivos não são classificados.

    
por AndrewWilliams 18.07.2018 / 01:12

2 respostas

0

Se os arquivos estiverem classificados, faça

comm -23 fileP.txt fileE.txt

comm compara dois arquivos classificados, procurando linhas que eles têm em comum. Por exemplo, dado este arquivo de cores cujos nomes começam com consoantes:

blue
green
purple
red
white
yellow

e esta lista de cores cujos nomes terminam com vogais:

blue
indigo
orange
purple
white

o comando comm colors1 colors2 produz esta saída:

                blue
green
        indigo
        orange
                purple
red
                white
yellow

onde:
a primeira coluna contém cores que começam e terminam com consoantes (em colors1 mas não colors2 ), a segunda coluna contém cores que começam e terminam com vogais (em colors2 mas não colors1 ), e a terceira coluna contém cores que começam com consoantes e terminam com vogais (em colors1 e colors2 ). Para seus arquivos (mostrados na sua pergunta), comm fileP.txt fileE.txt produz

                [email protected]:testtest
        [email protected]:testtest0
[email protected]:testtest1
                [email protected]:testtest2
                [email protected]:testtest3
[email protected]:testtest4
        [email protected]:testtest5

As opções são um pouco não intuitivas: -23 significa suprimir as segunda e terceira colunas, mostrando apenas o primeiro (linhas que estão no primeiro arquivo, mas não no segundo). Então,

$ comm -23 fileP.txt fileE.txt
[email protected]:testtest1
[email protected]:testtest4

Observe que isso não funcionará corretamente se os arquivos não estiverem classificados. Se os arquivos não estiverem classificados, classifique-os.

    
por 18.07.2018 / 03:54
0

Para ampliar em um comentário por xenoid , classifique os arquivos e digite

diff fileP.txt fileE.txt | sed -n 's/^< //p'

A saída de diff mostra as linhas que estão apenas no primeiro arquivo, precedido por , e as linhas que estão apenas no segundo arquivo, precedidas por . O sed seleciona apenas as linhas que começam com e as separa.

    
por 23.07.2018 / 04:27