Bashスクリプトで2つのファイルを比較しますか?

Bashスクリプトで2つのファイルを比較しますか?

シェルスクリプトの2つのファイルで一致するデータを見つけ、シェルの他のファイルに保存されている重複データを見つける方法は?

#!/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

コードを書きましたが、うまくいきませんでした。どのように書くのですか?

答え1

両方のファイルが同じであることをテストするには、次のようにします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

ユーティリティを「サイレント」にする-sフラグを指定します。cmp2つの同じファイルを比較すると、終了ステータスはcmp0になります。上記のコードでは、両方のファイルが同じかどうかに関するメッセージを印刷するために使用されます。


2つの入力ファイルがある場合パス名のリストが含まれています。比較するファイルを選択し、次の二重ループを使用します。

#!/bin/bash

filelist1="/home/vekomy/santhosh/bigfiles.txt"
filelist2="/home/vekomy/santhosh/bigfile2.txt"

mapfile -t files1 <"$filelist1"

while IFS= read -r file2; do
    for file1 in "${files1[@]}"; do
        if cmp -s "$file1" "$file2"; then
            printf 'The file "%s" is the same as "%s"\n' "$file1" "$file2"
        fi
    done
done <"$filelist2" | tee file-comparison.out

ここで結果は端末とファイルの両方で生成されますfile-comparison.out

両方の入力ファイルのパス名に改行文字が含まれていないとします。

files1コードは、ファイルの1つのすべてのパス名を配列として読み取ることから始まりますmapfile。他のファイルの各パス名のすべてのパス名を繰り返す必要があるため、ファイルを何度も読み取らないようにします。$filelist1内部ループから読み取るのではなく、配列の名前を繰り返していることがわかりますfiles1

答え2

最も簡単な方法はコマンドを使用することですdiff

例:

file1.txt最初のファイルが次のようになっているとします。

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

そして2番目のファイル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.

その後、diffを使用して、2つのファイル間でどの行が異なるかを自動的に表示できます。コマンドは次のとおりです。

diff file1.txt file2.txt

出力は次のとおりです。

 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.

この出力が何を意味するのか見てみましょう。覚えておくべき重要な点は、diffがこれらの違いを説明するときに指定されたコンテキスト内で説明することです。つまり、最初のファイルを2番目のファイルと一致するように変更する方法を教えてくれます。 diff 出力の最初の行には以下が含まれます。

  • 最初のファイルの行番号に対応します。
  • 文字(aは追加、cは変更、dは削除)
  • 2番目のファイルに対応する行番号。

上記の出力では、「2,4c2,4」意味: 「ライン2渡す4最初のファイルの内容をその行と一致するように変更する必要があります。2渡す42番目のファイルに。その後、各ファイルの次の行の内容をお知らせします。

  • < 先頭の行は最初のファイルの行です。
  • >前の行は2番目のファイルの行です。
  • 3 つのダッシュ ("---") は file1 と file2 の行のみを区切ります。

源泉

答え3

以下はファイル比較のための純粋なbashシェルスクリプトです:

#!/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

生産:

$ ./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.

読み取ったすべての行を表示するには、特定のコマンドのコメントを外して、最初の違いを見るとそのコマンドを終了させることができます。

ページを見るhttp://www.linuxjournal.com/content/reading-multiple-files-bashファイル記述子の詳細(例:「&3」)

頑張って...乾杯、drl

関連情報