쉘 스크립트의 두 파일에서 일치하는 데이터를 찾고 쉘의 다른 파일에 저장된 중복 데이터를 찾는 방법은 무엇입니까?
#!/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