Bash 스크립트에서 두 파일을 비교하시겠습니까?

Bash 스크립트에서 두 파일을 비교하시겠습니까?

쉘 스크립트의 두 파일에서 일치하는 데이터를 찾고 쉘의 다른 파일에 저장된 중복 데이터를 찾는 방법은 무엇입니까?

#!/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하도록 플래그를 지정합니다 . cmp두 개의 동일한 파일을 비교할 때 종료 상태 cmp는 0이 됩니다. 위 코드에서는 두 파일이 동일한지 여부에 대한 메시지를 인쇄하는 데 사용됩니다.


두 개의 입력 파일이 있는 경우경로 이름 목록을 포함합니다.비교하려는 파일을 선택한 다음 다음과 같은 이중 루프를 사용하십시오.

#!/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코드는 파일 중 하나의 모든 경로 이름을 배열로 읽는 것으로 시작됩니다 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.`

그리고 두 번째 파일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를 사용하여 두 파일 간에 어떤 줄이 다른지 자동으로 표시할 수 있습니다. 명령은 다음과 같습니다.

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가 이러한 차이점을 설명할 때 지정된 컨텍스트 내에서 설명한다는 것입니다. 즉, 첫 번째 파일을 두 번째 파일과 일치하도록 변경하는 방법을 알려줍니다. diff 출력의 첫 번째 줄에는 다음이 포함됩니다.

  • 첫 번째 파일의 줄 번호에 해당합니다.
  • 문자(a는 추가, c는 변경, d는 삭제)
  • 두 번째 파일에 해당하는 줄 번호입니다.

위의 출력에서,"2,4c2,4"의미: "라인2통과하다4첫 번째 파일의 내용을 해당 줄과 일치하도록 변경해야 합니다.2통과하다4두 번째 파일에. ” 그런 다음 각 파일에 있는 다음 줄의 내용을 알려줍니다.

  • < 앞에 오는 줄은 첫 번째 파일의 줄입니다.
  • > 앞의 줄은 두 번째 파일의 줄입니다.
  • 세 개의 대시("---")는 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

관련 정보