Então, basicamente, o que eu quero fazer é comparar dois arquivos por linha pela coluna 2. Como eu poderia fazer isso?
Arquivo_1.txt:
User1 US
User2 US
User3 US
Arquivo_2.txt:
User1 US
User2 US
User3 NG
Arquivo de saída:
User3 has changed
command-line
text-processing
Roboman1723
fonte
fonte
diff "File_1.txt" "File_2.txt"
Respostas:
Olhe para o
diff
comando. É uma boa ferramenta, e você pode ler tudo sobre isso digitandoman diff
no seu terminal.O comando que você deseja executar é o
diff File_1.txt File_2.txt
que produzirá a diferença entre os dois e deve ser algo como isto:Uma observação rápida sobre a leitura da saída do terceiro comando: As 'setas' (
<
e>
) referem-se ao valor da linha no arquivo esquerdo (<
) versus o arquivo direito (>
), sendo o arquivo esquerdo o que você digitou primeiro na linha de comando, neste casoFile_1.txt
Além disso, você pode notar que o quarto comando é
diff ... | tee Output_File
canalizar os resultados dediff
para em umtee
, que coloca a saída em um arquivo, para que você possa salvá-lo para mais tarde, se não quiser ver tudo no console naquele segundo.fonte
diff file1 file2 -s
. Aqui está um exemplo: imgur.com/ShrQx9xOu você pode usar Meld Diff
Instale executando:
Seu exemplo:
Comparar diretório:
Exemplo com texto completo:
fonte
Você pode usar o vimdiff .
Exemplo:
fonte
dos
e o segundounix
.FWIW, eu gosto bastante do que recebo com a saída lado a lado do diff
daria algo como:
fonte
Você pode usar o comando
cmp
:saída seria
fonte
cmp
é muito mais rápido do quediff
se tudo o que você deseja é o código de retorno.Meld
é realmente uma ótima ferramenta. Mas você também pode usardiffuse
para comparar visualmente dois arquivos:fonte
Permanecendo fielmente à pergunta (arquivo1, arquivo2, arquivo de saída com a mensagem "mudou"), o script abaixo funciona.
Copie o script em um arquivo vazio, salve-o como
compare.py
, torne-o executável, execute-o pelo comando:O script:
Com algumas linhas extras, você pode imprimir em um arquivo de saída ou no terminal, dependendo se o arquivo de saída estiver definido:
Para imprimir em um arquivo:
Para imprimir na janela do terminal:
O script:
fonte
Uma maneira fácil é usar
colordiff
, que se comporta como,diff
mas coloriza sua saída. Isso é muito útil para a leitura de diferenças. Usando seu exemplo,onde a
u
opção fornece um diff unificado. É assim que o diff colorido se parece:Instale
colordiff
executandosudo apt-get install colordiff
.fonte
Resposta adicional
Se não for necessário saber quais partes dos arquivos diferem, você pode usar a soma de verificação do arquivo. Há muitas maneiras de fazer isso, usando
md5sum
ousha256sum
. Basicamente, cada um deles gera uma sequência na qual o arquivo contém um hash. Se os dois arquivos forem iguais, o hash também será o mesmo. Isso geralmente é usado quando você baixa software, como imagens iso de instalação do Ubuntu. Eles geralmente são usados para verificar a integridade de um conteúdo baixado.Considere o script abaixo, onde você pode fornecer dois arquivos como argumentos, e o arquivo informará se eles são iguais ou não.
Exemplo de execução:
Resposta mais antiga
Além disso, existe um
comm
comando que compara dois arquivos classificados e fornece saída em três colunas: coluna 1 para itens exclusivos para o arquivo nº 1, coluna 2 para itens exclusivos para o arquivo nº 2 e coluna 3 para itens presentes nos dois arquivos.Para suprimir qualquer coluna, você pode usar as opções -1, -2 e -3. Usar -3 mostrará as linhas que diferem.
Abaixo, você pode ver a captura de tela do comando em ação.
Há apenas um requisito - os arquivos devem ser classificados para serem comparados corretamente.
sort
comando pode ser usado para esse fim. Abaixo está outra captura de tela, na qual os arquivos são classificados e depois comparados. As linhas começando à esquerda entre o arquivo_1 e as linhas iniciando na coluna 2 pertencem apenas ao arquivo_2fonte
Instale o git e use
E você obterá saída em bom formato colorido
Instalação do Git
fonte
colcmp.sh
Compara pares de nome / valor em 2 arquivos no formato
name value\n
. Grava oname
paraOutput_file
se alterado. Requer bash v4 + para matrizes associativas .Uso
Arquivo de saída
Origem (colcmp.sh)
Explicação
Repartição do código e o que isso significa, da melhor forma possível. Congratulo-me com edições e sugestões.
Comparação básica de arquivos
O cmp definirá o valor de $? da seguinte maneira :
Eu escolhi usar um caso .. instrução esac para avaliar $? porque o valor de $? muda após cada comando, incluindo test ([).
Alternativamente, eu poderia ter usado uma variável para armazenar o valor de $? :
Acima faz o mesmo que a declaração do caso. IDK que eu gosto mais.
Limpe a saída
Acima limpa o arquivo de saída, portanto, se nenhum usuário for alterado, o arquivo de saída estará vazio.
Eu faço isso dentro das instruções case para que o Output_file permaneça inalterado por erro.
Copiar arquivo do usuário para o shell script
Acima, copia o arquivo_1.txt para o diretório inicial do usuário atual.
Por exemplo, se o usuário atual for john, o item acima seria o mesmo que cp "File_1.txt" /home/john/.colcmp.arrays.tmp.sh
Escapar caracteres especiais
Basicamente, sou paranóico. Eu sei que esses caracteres podem ter um significado especial ou executar um programa externo quando executados em um script como parte da atribuição de variável:
O que não sei é o quanto não sei sobre o bash. Não sei que outros personagens podem ter um significado especial, mas quero escapar de todos eles com uma barra invertida:
O sed pode fazer muito mais do que a correspondência de padrões de expressão regular . O padrão de script "s / (localizar) / (substituir) /" executa especificamente a correspondência de padrões.
"s / (localizar) / (substituir) / (modificadores)"
em inglês: capture qualquer pontuação ou caractere especial como grupo de captura 1 (\\ 1)
em inglês: prefixe todos os caracteres especiais com uma barra invertida
em inglês: se mais de uma correspondência for encontrada na mesma linha, substitua-as todas
Comentar o script inteiro
Acima usa uma expressão regular para prefixar todas as linhas de ~ / .colcmp.arrays.tmp.sh com um caractere de comentário básico ( # ). Faço isso porque mais tarde pretendo executar ~ / .colcmp.arrays.tmp.sh usando o comando source e porque não sei ao certo todo o formato do arquivo_1.txt .
Não quero executar acidentalmente código arbitrário. Eu acho que ninguém faz.
"s / (localizar) / (substituir) /"
em inglês: capture cada linha como grupo de captura 1 (\\ 1)
em inglês: substitua cada linha por um símbolo de libra seguido pela linha que foi substituída
Converter valor do usuário em A1 [Usuário] = "valor"
Acima está o núcleo deste script.
#User1 US
A1[User1]="US"
A2[User1]="US"
(para o 2º arquivo)"s / (localizar) / (substituir) /"
em inglês:
capture o restante da linha como grupo de captura 2
(substituir) = A1 \\ [\\ 1 \\] = \ "\\ 2 \"
A1[
para iniciar a atribuição da matriz em uma matriz chamadaA1
]="
]
= atribuição de matriz fechada, por exemplo,A1[
Usuário1]="
US"
=
= operador de atribuição, por exemplo, variável = valor"
= quote quote para capturar espaços ... embora agora que eu pense sobre isso, teria sido mais fácil deixar o código acima que inverte tudo para também inverter caracteres de espaço.em inglês: substitua cada linha no formato
#name value
por um operador de atribuição de matriz no formatoA1[name]="value"
Tornar executável
Acima, usa chmod para tornar o arquivo de script da matriz executável.
Não tenho certeza se isso é necessário.
Declarar matriz associativa (bash v4 +)
O capital -A indica que as variáveis declaradas serão matrizes associativas .
É por isso que o script requer o bash v4 ou superior.
Executar nosso script de atribuição de variável de matriz
Nós já temos:
User value
para linhas deA1[User]="value"
,Acima, fornecemos o script para executá-lo no shell atual. Fazemos isso para manter os valores das variáveis que são definidos pelo script. Se você executar o script diretamente, ele gera um novo shell, e os valores das variáveis são perdidos quando o novo shell sai, ou pelo menos esse é o meu entendimento.
Isso deve ser uma função
Fazemos a mesma coisa por US $ 1 e A1 que fazemos por US $ 2 e A2 . Realmente deveria ser uma função. Eu acho que neste momento esse script é bastante confuso e funciona, então não vou corrigi-lo.
Detectar usuários removidos
Loops acima através de chaves de matriz associativas
Acima, usa a substituição de variável para detectar a diferença entre um valor não definido e uma variável que foi explicitamente definida como uma cadeia de comprimento zero.
Aparentemente, existem várias maneiras de verificar se uma variável foi definida . Eu escolhi aquele com mais votos.
Acima adiciona o usuário $ i ao Output_File
Detectar usuários adicionados ou alterados
Acima limpa uma variável para que possamos rastrear os usuários que não foram alterados.
Loops acima através de chaves de matriz associativas
Acima usa a substituição de variável para verificar se uma variável foi configurada .
Como $ i é a chave da matriz (nome do usuário), $ A2 [$ i] deve retornar o valor associado ao usuário atual de File_2.txt .
Por exemplo, se $ i for Usuário1 , o texto acima será lido como $ {A2 [Usuário1]}
Acima adiciona o usuário $ i ao Output_File
Como $ i é a chave da matriz (nome do usuário), $ A1 [$ i] deve retornar o valor associado ao usuário atual do File_1.txt e $ A2 [$ i] deve retornar o valor do File_2.txt .
Acima, compara os valores associados ao usuário $ i dos dois arquivos.
Acima adiciona o usuário $ i ao Output_File
Acima cria uma lista separada por vírgula de usuários que não foram alterados. Observe que não há espaços na lista; caso contrário, a próxima verificação precisará ser citada.
Acima, o relatório informa o valor de $ USERSWHODIDNOTCHANGE, mas apenas se houver um valor em $ USERSWHODIDNOTCHANGE . Da maneira como está escrito, $ USERSWHODIDNOTCHANGE não pode conter espaços. Se precisar de espaços, acima pode ser reescrito da seguinte maneira:
fonte