Como posso obter o diff para mostrar apenas linhas adicionadas e excluídas? Se o diff não pode fazê-lo, que ferramenta pode?
diff A B | grep '^[<>]'
comm
.
Como posso obter o diff para mostrar apenas linhas adicionadas e excluídas? Se o diff não pode fazê-lo, que ferramenta pode?
diff A B | grep '^[<>]'
comm
.
Respostas:
Outra maneira de ver isso:
Mostrar linhas que existem apenas no arquivo a: (ou seja, o que foi excluído de a)
comm -23 a b
Mostrar linhas que existem apenas no arquivo b: (ou seja, o que foi adicionado a b)
comm -13 a b
Mostrar linhas que existem apenas em um arquivo ou no outro: (mas não ambos)
comm -3 a b | sed 's/^\t//'
(Aviso: se o arquivo a
tiver linhas que começam com TAB, ele (o primeiro TAB) será removido da saída.)
NOTA: Os dois arquivos precisam ser classificados para comm
funcionarem corretamente. Se eles ainda não estiverem classificados, você deve classificá-los:
sort <a >a.sorted
sort <b >b.sorted
comm -12 a.sorted b.sorted
Se os arquivos forem extremamente longos, isso pode ser um fardo, pois requer uma cópia extra e, portanto, duas vezes mais espaço em disco.
comm -12 <(sort a) <(sort b)
comm
pode fazer o que quiser. Na sua página de manual:
DESCRIÇÃO
Compare os arquivos classificados FILE1 e FILE2 linha por linha.
Sem opções, produza saída de três colunas. A coluna um contém linhas exclusivas para FILE1, a coluna dois contém linhas exclusivas para FILE2 e a coluna três contém linhas comuns aos dois arquivos.
Estas colunas são suppressable com -1
, -2
e -3
respectivamente.
Exemplo:
[root@dev ~]# cat a
common
shared
unique
[root@dev ~]# cat b
common
individual
shared
[root@dev ~]# comm -3 a b
individual
unique
E se você quer apenas as linhas exclusivas e não se importa em qual arquivo elas estão:
[root@dev ~]# comm -3 a b | sed 's/^\t//'
individual
unique
Como diz a página do manual, os arquivos devem ser classificados com antecedência.
Para mostrar adições e exclusões sem contexto, números de linhas, +, -, <,>! etc, você pode usar o diff assim:
diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt
Por exemplo, dados dois arquivos:
a.txt
Common
Common
A-ONLY
Common
b.txt
Common
B-ONLY
Common
Common
O comando a seguir mostrará as linhas removidas de a ou adicionadas a b:
diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt
resultado:
B-ONLY
A-ONLY
Este comando ligeiramente diferente mostrará as linhas removidas do a.txt:
diff --changed-group-format='%<' --unchanged-group-format='' a.txt b.txt
resultado:
A-ONLY
Por fim, este comando mostrará linhas adicionadas ao a.txt
diff --changed-group-format='%>' --unchanged-group-format='' a.txt b.txt
resultado
B-ONLY
Isso é o que diff faz por padrão ... Talvez você precise adicionar alguns sinalizadores para ignorar o espaço em branco?
diff -b -B
deve ignorar linhas em branco e diferentes números de espaços.
Não, diff
na verdade não mostra as diferenças entre dois arquivos da maneira que se pensa. Ele produz uma sequência de comandos de edição para uma ferramenta que patch
é usada para mudar um arquivo para outro.
A dificuldade para qualquer tentativa de fazer o que você está procurando é como definir o que constitui uma linha que foi alterada versus uma excluída, seguida por uma adicionada. Também o que fazer quando as linhas são adicionadas, excluídas e alteradas adjacentes umas às outras.
diff
fontes, mas me lembro de todos os tipos de variações para acompanhar onde dois arquivos correspondem para ficar sincronizados e acho que há um limite para desistir com base na distância entre os arquivos. linhas são. Mas não me lembro de nenhuma correspondência intra-linha, exceto pelo espaço em branco recolhido (opcionalmente) ou caso de ignorância. Ou (talvez) palavras para esse efeito. De qualquer forma, tudo se patch
resume e o "vgrep" aparece para o passeio. Talvez. Na terça-feira.
As ferramentas de comparação visual ajustam dois arquivos, para que um segmento com o mesmo número de linhas, mas com conteúdo diferente, seja considerado um segmento alterado. Linhas completamente novas entre segmentos correspondentes são consideradas segmentos adicionados.
É também assim que a ferramenta de linha de comando sdiff funciona, que mostra uma comparação lado a lado de dois arquivos em um terminal. As linhas alteradas são separadas por | personagem. Se uma linha existir apenas no arquivo A, <será usado como caractere separador. Se uma linha existir apenas no arquivo B,> será usado como separador. Se você não tiver caracteres <e> nos arquivos, poderá usar isso para mostrar apenas linhas adicionadas:
sdiff A B | grep '[<>]'
Obrigado senarvi, sua solução (que não foi votada) na verdade me deu EXATAMENTE o que eu queria depois de procurar por séculos em várias páginas.
Usando sua resposta, aqui está o que eu criei para alterar a lista / adicionar / excluir. O exemplo usa 2 versões do arquivo / etc / passwd e imprime o nome de usuário para os registros relevantes.
#!/bin/bash
sdiff passwd1 passwd2 | grep '[|]' | awk -F: '{print "changed: " $1}'
sdiff passwd1 passwd2 | grep '[<]' | awk -F: '{print "deleted: " $1}'
sdiff passwd1 passwd2 | grep '[>]' | awk -F\> '{print $2}' | awk -F: '{print "added: " $1}'
Acho esse formulário em particular frequentemente útil:
diff --changed-group-format='-%<+%>' --unchanged-group-format='' f g
Exemplo:
printf 'a\nb\nc\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format='' \
f g
Resultado:
-b
-c
+B
+C
-e
-f
+E
+F
Portanto, mostra as linhas antigas com -
seguidas imediatamente pela nova linha correspondente com +
.
Se tivéssemos uma exclusão de C
:
printf 'a\nb\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format='' \
f g
Se parece com isso:
-b
+B
+C
-e
-f
+E
+F
O formato está documentado em man diff
:
--line-format=LFMT
format all input lines with LFMT`
e:
LTYPE is 'old', 'new', or 'unchanged'.
GTYPE is LTYPE or 'changed'.
e:
LFMT (only) may contain:
%L contents of line
%l contents of line, excluding any trailing newline
[...]
Pergunta relacionada: https://stackoverflow.com/questions/15384818/how-to-get-the-difference-only-additions-between-two-files-in-linux
Testado no Ubuntu 18.04.
Arquivo1:
text670_1
text067_1
text067_2
Arquivo2:
text04_1
text04_2
text05_1
text05_2
text067_1
text067_2
text1000_1
Usar:
diff -y file1 file2
Isso mostra duas colunas para arquivos de perspectivas.
Resultado:
text670_1
> text04_1
> text04_2
> text05_1
> text05_2
text067_1 text67_1
text067_2 text67_2
> text1000_1