Como comparar dois arquivos e linhas de saída que não aparecem no primeiro?


4

Se eu tiver um arquivo A contendo uma lista de campos:

2017-04-23
2017-04-30
2017-05-07
2017-05-14
2017-05-21
2017-05-28
2017-06-04
2017-06-11
2017-06-18
2017-06-25

E outro arquivo B contendo uma lista de campos:

2017-04-23
2017-04-30
2017-05-07
2017-05-14
2017-05-21
2017-05-28
2017-06-04
2017-06-11
2017-06-18
2017-06-25
2017-07-02
2017-07-09
2017-07-16
2017-07-23

Como posso rapidamente diferenciar esses dois arquivos onde quero saber todos os campos no arquivo B que são não presente no arquivo A?

Este não é um diff regular onde eu quero ver uma diferença relativa entre os arquivos, mas mais como uma comparação de hash, onde cada linha é uma entrada em um mapa. Eu quero obter uma lista de todas as linhas no arquivo B que não estão presentes no arquivo A para que eu possa removê-los onde cada linha do arquivo A representa um diretório que deve ser preservado.

Eu estou procurando uma solução Bash / CoreUtils.

Respostas:


3

Se seus arquivos estão classificados, você pode usar comm :

$ comm -13 A B
2017-07-02
2017-07-09
2017-07-16
2017-07-23

com opções:

  • -1: suprime a coluna 1 (linhas exclusivas para FILE1)
  • -3: suprima a coluna 3 (linhas que aparecem nos dois arquivos)

1
E se eles não estão classificados, você pode classificá-los com a substituição do processo <(sort filename)
Barmar

2

grep é a ferramenta certa para o trabalho, embora não seja nem Bash nem da CoreUtils:

grep -Fxvf A B

Todas essas opções são compatíveis com POSIX. De man 1 grep:

-f pattern_file

Leia um ou mais padrões do arquivo nomeado pelo nome do caminho pattern_file. Padrões em pattern_file será rescindido por: a. Um padrão nulo pode ser especificado por uma linha vazia em pattern_file. A menos que o -E ou -F opção também é especificada, cada padrão deve ser tratado como um BRE, conforme descrito no volume de Definições de Base de POSIX.1-2008, Seção 9.3, Expressões Regulares Básicas.

-F

Corresponder usando strings fixas. Trate cada padrão especificado como uma string em vez de uma expressão regular. Se uma linha de entrada contiver algum dos padrões como uma seqüência contígua de bytes, a linha deverá ser correspondida. Uma string nula deve corresponder a todas as linhas.

-v

Selecione linhas que não correspondam a nenhum dos padrões especificados. Se o -v opção não é especificada, as linhas selecionadas devem ser aquelas que correspondem a qualquer um dos padrões especificados.

-x

Considere apenas as linhas de entrada que usam todos os caracteres na linha, excluindo a terminação para corresponder uma cadeia fixa inteira ou uma expressão regular a linhas correspondentes.


1

Outra maneira com alguns canos

cat A B|sort|uniq -u

editar- UUOC

Não há necessidade de gato

sort A B|uniq -u

Isso trata A e B igualmente, enquanto no problema original esses arquivos não são intercambiáveis. E se houver uma linha em A que não está em B?
Kamil Maciorowski

@Kamil Sim, você está certo. Eu não entendi a pergunta, isso vai imprimir todas as linhas não duplicadas em ambos os arquivos, o que não é o que o OP quer.
Paulo

1
Consertar: sort A A B | uniq -u. :)
Kamil Maciorowski

Ele funciona :) boa correção. Mas há outro problema com a minha solução, a saída aparecerá classificada, talvez seja um problema para fins do OP.
Paulo

Você leu o último parágrafo da pergunta? Ele só quer obter uma lista de diretórios para remover, não parece que a ordem é importante. Além disso, seus arquivos de entrada parecem estar classificados.
Barmar
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.