Comparação de dois arquivos no script bash?

Como encontrar dois arquivos com dados correspondentes no shell script e armazenamento de dados duplicado em outro arquivo no shell?

#!/bin/bash file1="/home/vekomy/santhosh/bigfiles.txt" file2="/home/vekomy/santhosh/bigfile2.txt" while read -r $file1; do while read -r $file2 ;do if [$file1==$file2] ; then echo "two files are same" else echo "two files content different" fi done done 

Escrevi código, mas não funcionou. Como escrevê-lo?

Comentários

  • Você tentou usar diff comando?

Resposta

Para testar apenas se dois os arquivos são iguais, use cmp -s:

#!/bin/bash file1="/home/vekomy/santhosh/bigfiles.txt" file2="/home/vekomy/santhosh/bigfile2.txt" if cmp -s "$file1" "$file2"; then printf "The file "%s" is the same as "%s"\n" "$file1" "$file2" else printf "The file "%s" is different from "%s"\n" "$file1" "$file2" fi 

O -s sinalizar para cmp tornará o utilitário “silencioso”. O status de saída de cmp será zero ao comparar dois arquivos que são idênticos. Isso é usado no código acima para imprimir uma mensagem sobre se os dois arquivos são idênticos ou não.


Se seus dois arquivos de entrada contém uma lista de nomes de caminho de arquivos que você deseja comparar e, em seguida, use um loop duplo como este:

  

Aqui, o resultado é produzido no terminal e no arquivo file-comparison.out.

Presume-se que nenhum nome de caminho nos dois arquivos de entrada contenha novas linhas incorporadas.

O código primeiro lê todos os nomes de caminho de um dos arquivos em uma matriz, files1, usando mapfile. Faço isso para evitar ter que ler esse arquivo mais de uma vez, pois teremos que passar por todos os nomes de caminho para cada nome de caminho no outro arquivo. Você notará que, em vez de ler $filelist1 no loop interno, eu apenas itero sobre os nomes na matriz files1.

Comentários

  • i need total progam in bash shell
  • @santhoshreddy Veja a resposta atualizada.

Resposta

A maneira mais fácil é usar o comando diff.

exemplo:

Suponhamos que o primeiro arquivo seja file1.txt e ele contém:

I need to buy apples. I need to run the laundry. I need to wash the dog. I need to get the car detailed.` 

e o segundo arquivo file2.txt

I need to buy apples. I need to do the laundry. I need to wash the car. I need to get the dog detailed. 

então podemos usar diff para exibir automaticamente para nós quais linhas diferem entre os dois arquivos com este comando:

diff file1.txt file2.txt

e a saída será:

 2,4c2,4 < I need to run the laundry. < I need to wash the dog. < I need to get the car detailed. --- > I need to do the laundry > I need to wash the car. > I need to get the dog detailed. 

Vamos dar uma olhada no que esta saída significa. O importante a lembrar é que quando diff está descrevendo essas diferenças para você, ele está fazendo isso em um contexto prescritivo: ele está dizendo a você como alterar o primeiro arquivo para fazê-lo corresponder ao segundo arquivo. A primeira linha da saída diff conterá:

  • números de linha correspondentes ao primeiro arquivo,
  • uma letra (a para adicionar, c para alterar ou d para excluir )
  • números de linha correspondentes ao segundo arquivo.

Em nossa saída acima, “2,4c2,4 “ significa:” Linhas 2 a 4 no primeiro arquivo precisa ser alterado para corresponder às linhas 2 a 4 no segundo arquivo. ” Em seguida, ele nos diz quais são essas linhas em cada arquivo:

  • As linhas precedidas por < são linhas do primeiro arquivo;
  • linhas precedidas por> são linhas do segundo arquivo.
  • Os três travessões (“—“) apenas separam as linhas do arquivo 1 e do arquivo 2.

Fonte

Resposta

Aqui está um puro script bash shell para comparar arquivos:

#!/usr/bin/env bash # @(#) s1 Demonstrate rudimentary diff using shell only. # Infrastructure details, environment, debug commands for forum posts. # Uncomment export command to run as external user: not context, pass-fail. # export PATH="/usr/local/bin:/usr/bin:/bin" set +o nounset LC_ALL=C ; LANG=C ; export LC_ALL LANG pe() { for _i;do printf "%s" "$_i";done; printf "\n"; } pl() { pe;pe "-----" ;pe "$*"; } db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; } db() { : ; } C=$HOME/bin/context && [ -f "$C" ] && $C set -o nounset FILE1=${1-data1} shift FILE2=${1-data2} # Display samples of data files. pl " Data files:" head "$FILE1" "$FILE2" # Set file descriptors. exec 3<"$FILE1" exec 4<"$FILE2" # Code based on: # http://www.linuxjournal.com/content/reading-multiple-files-bash # Section 2, solution. pl " Results:" eof1=0 eof2=0 count1=0 count2=0 while [[ $eof1 -eq 0 || $eof2 -eq 0 ]] do if read a <&3; then let count1++ # printf "%s, line %d: %s\n" $FILE1 $count1 "$a" else eof1=1 fi if read b <&4; then let count2++ # printf "%s, line %d: %s\n" $FILE2 $count2 "$b" else eof2=1 fi if [ "$a" != "$b" ] then echo " File $FILE1 and $FILE2 differ at lines $count1, $count2:" pe "$a" pe "$b" # exit 1 fi done exit 0 

produzindo:

$ ./s1 Environment: LC_ALL = C, LANG = C (Versions displayed with local utility "version") OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64 Distribution : Debian 8.9 (jessie) bash GNU bash 4.3.30 ----- Data files: ==> data1 <== I need to buy apples. I need to run the laundry. I need to wash the dog. I need to get the car detailed. ==> data2 <== I need to buy apples. I need to do the laundry. I need to wash the car. I need to get the dog detailed. ----- Results: File data1 and data2 differ at lines 2, 2: I need to run the laundry. I need to do the laundry. File data1 and data2 differ at lines 3, 3: I need to wash the dog. I need to wash the car. File data1 and data2 differ at lines 4, 4: I need to get the car detailed. I need to get the dog detailed. 

Os comentários sobre comandos específicos podem ser removidos para sair na primeira diferença vista, e se você deseja ver todas as linhas lidas.

Veja a página em http://www.linuxjournal.com/content/reading-multiple-files-bash para obter detalhes sobre os descritores de arquivo, como “& 3”.

Cumprimentos … saudações, drl

Comentários

  • head é um utilitário externo e o que é $HOME/bin/context? E o que os comentários significam no topo?
  • Head exibe a entrada. Ele não joga à parte na diferenciação. Tal como acontece com alguns outros itens, ” contexto ” é local para mostrar o contexto do ambiente. Ao incluir isso, não ‘ não precisamos discutir se as versões dos sistemas operacionais e utilitários são diferentes.
  • Havia uma exportação faltando, obrigado por notar isso.
  • Ainda não ‘ não entendo o comentário.O que ‘ é um ” usuário externo “, e por que você deseja definir o caminho para um script que é puro bash?
  • Escrevemos código para nossa loja, então as configurações de caminho podem ser diferentes para usuários externos. Acrescentamos que se parecer necessário omitir nossas configurações. Este é um modelo que é modificado para exibir as informações sobre o ambiente no qual o código foi executado. Se fosse transformado em um código de produção, digamos para clientes, em vez de um código de demonstração, ‘ queremos ter certeza de que nenhum de nossos caminhos locais serão usados. A linha de comando para o contexto é projetado de forma que, se esse arquivo não for encontrado, nada acontecerá, nem mesmo um erro, mas nenhuma versão será listada.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *