Compare duas listas de URLs e imprima URLs recém-adicionados a um novo arquivo

8

Inicialmente, estou produzindo dois arquivos que contêm listas de URLs - os referirei como olde new. Gostaria de comparar os dois arquivos e, se houver algum URL no newarquivo que não esteja no oldarquivo, gostaria que eles fossem exibidos em um extra_urlsarquivo.

Agora, eu li algumas coisas sobre o uso do diffcomando, mas pelo que sei, isso também analisa a ordem das informações. Não quero que a ordem tenha nenhum efeito na saída. Eu só quero que os URLs extras sejam newimpressos no extra_urlsarquivo, independentemente da ordem em que eles são colocados nos outros dois arquivos.

Como posso fazer isso?

neilH
fonte

Respostas:

14

Você pode usar o commcomando para comparar dois arquivos e mostrar seletivamente linhas exclusivas para um ou outro, ou as linhas em comum. Requer que as entradas sejam classificadas, mas você pode classificá-las em tempo real, usando a substituição de processo.

comm -13 <(sort old.txt) <(sort new.txt)

Se você estiver usando uma versão bashque não suporta substituição de processo, ela poderá ser emulada usando pipes nomeados. Um exemplo é mostrado na Wikipedia .

Barmar
fonte
Conciso, mas eficaz - exatamente o que era necessário, excelente parte do código para o que eu precisava.
23515 neilH
Hmm, mas se a entrada for classificada, difffará a mesma coisa, certo?
justhalf
diffmostrará todas as diferenças. commpermite que você selecione se deseja ver as linhas do arquivo 1, arquivo 2 ou as que têm em comum.
Barmar
Oi Barmar, não tenho certeza de que você irá verificar isso, mas apenas no caso, mudei esse script para o meu Synology Nas para executar a partir daí. Desde a execução do meu script na Synology, agora estou recebendo o erro de sintaxe: linha 60: erro de sintaxe: inesperado "("
neilH
Qual versão bashestá sendo executada? Pode não suportar a substituição do processo.
Barmar
6

Eu usaria apenas grep:

grep -vFf old new > extra_urls

Explicação

  • -f: diz greppara ler seus padrões de pesquisa de um arquivo. Nesse caso old,.
  • -v : diz ao grep para inverter a correspondência, para imprimir apenas linhas não correspondentes.
  • -F: diz ao grep para interpretar seus padrões de pesquisa como strings, não como expressões regulares. Dessa forma, o .URL será correspondido literalmente.

Combinadas, elas grepimprimem as linhas newque não estavam old. A ordem dos URLs no arquivo é irrelevante.

terdon
fonte
Oi Terdon, Obrigado pela sua contribuição. Acabei de testar isso e ele produziu um arquivo "URLs extras" em branco, apesar de haver novos URLs no arquivo "novo".
23415 neilH
@ bms9nmh hmm, isso é estranho. Por favor edite sua pergunta para dar um exemplo de seus arquivos de entrada. Você também pode entrar na sala de bate-papo do site, onde podemos discutir mais sobre isso.
terdon
2
Você deseja adicionar -Fpadrões de texto simples
glenn jackman
1

Como a ordem é importante para você, use awk

awk '
    NR == FNR {old[$1]=1; next}
    !($1 in old)
' old new > extra
Glenn Jackman
fonte
1
Oi Glen, só para esclarecer, a ordem não é importante. A ordem do URL não é um problema, apenas a diferença entre os dois arquivos, ou seja, os URLs adicionais. Não quero a diferença para efetuar a saída de forma alguma.
23415 neilH
@ bms9nmh: você pode simplesmente mudar > extrapara | sort > extra. ou | sort -u > extrase você deseja que apenas um novo URL apareça na saída uma vez, independentemente de quantas vezes ele esteja na entrada. A ordem de entrada pode afetar a ordem de saída, a menos que você faça um trabalho extra em algum lugar ao longo do caminho para evitá-la.
Steve Jessop
@ Steve, meh, commé a melhor resposta para esta pergunta, embora grep -Fvfé muito bom
glenn jackman
0

Eu tenho um aplicativo chamado meld. Permite visualizar os dois (ou três) arquivos, lado a lado, mostra as diferenças e permite a cópia seletiva de um para o outro ou a exclusão de caracteres.

O Meld pode ser instalado a partir de um terminal com

sudo apt-get install meld 
krazykyngekorny
fonte