Como testar quais strings do Arquivo A não estão presentes no Arquivo B, sem exibir nada que esteja presente no Arquivo B e não no Arquivo A?

0

Eu tenho um arquivo de texto, digamos sitelist1.txt (Arquivo A), que tem alguns URLs, como abaixo:

http://www.facebook.com
http://www.twitter.com
http://myspace.com/profile
http://orkut.com/archived

Eu tenho outro arquivo de texto, digamos sitelist2.txt (Arquivo B), que possui vários URLs existentes.

Eu tentei:

fgrep -v -f sitelist1.txt sitelist2.txt 

O problema é - Isso também exibe as URLs presentes no sitelist2.txt e não no sitelist1.txt

    
por Koshur 28.03.2016 / 16:55

3 respostas

3

O -v que você passou está fazendo com que ele faça o oposto do que você pretende - está mostrando a você, para cada linha em sitelist1.txt , todas as linhas em sitelist2.txt que não são correspondências. Então você está vendo um monte de duplicatas, eu apostaria. Você quer usar o mesmo comando sem a opção -v :

fgrep -f sitelist1.txt sitelist2.txt

Isso executará a seguinte diretiva em inglês: Para cada linha em sitelist1.txt , mostre-me todas as linhas em sitelist2.txt que contêm a linha do arquivo 1 na qual estou interessado, como a linha inteira ou como parte do arquivo 2 linha.

A opção -v é uma opção "inverter correspondência", que mostra todas as linhas não correspondentes.

    
por 28.03.2016 / 17:00
2

A resposta de João (além do mal-entendido apontado nos comentários sob a pergunta) é a resposta para a pergunta, no entanto eu gostaria de salientar que para operações simples como esta combine (parte de moreutils ) é uma boa escolha; é muito fácil de usar, pois permite expressar a operação a ser feita usando operadores booleanos (suportados por AND, OR, NOT e XOR):

combine sitelist1.txt NOT sitelist2.txt
% cat sitelist1.txt 
http://www.facebook.com
http://www.twitter.com
http://myspace.com/profile
http://orkut.com/archived
% cat sitelist2.txt 
http://www.facebook.com
http://www.twitter.com
http://myspace.com/profile
% combine sitelist1.txt NOT sitelist2.txt
http://orkut.com/archived

Ao contrário da maioria dos utilitários, os arquivos de entrada não precisam ser classificados (embora eu ache que eles ainda estejam classificados internamente), mas quando usar fgrep , há uma armadilha caso de linhas duplicadas em sitelist1.txt que não se deseja imprimir. Se sitelist1.txt contiver linhas duplicadas e você não quiser imprimi-las, será necessário enviar a saída combine para sort -u :

combine sitelist1.txt NOT sitelist2.txt | sort -u
    
por 28.03.2016 / 18:04
2

Se você estiver procurando URLs completos em cada linha e não substrings, poderá usar comm

comm -23 <(sort -u fileA) <(sort -u fileB)

Explicação:
comm espera entrada classificada, então primeiro classificamos e criamos os arquivos 2 (sort -u file) . Próximo - use a substituição de processo para transmitir a saída de sort -u como um "arquivo" para comunicação, pois o comm espera arquivos: comm <() <() .
Last - suprima as colunas 2 (linhas exclusivas do arquivo B) e 3 (linhas comuns aos dois arquivos) para produzir apenas linhas na coluna 1 (linhas exclusivas do arquivo A).

    
por 28.03.2016 / 18:32