IT박스

두 파일을 한 줄씩 비교하고 다른 파일에서 차이를 생성

itboxs 2020. 7. 28. 08:16
반응형

두 파일을 한 줄씩 비교하고 다른 파일에서 차이를 생성


file1을 file2와 비교하고 file2에없는 file1의 행을 포함하는 file3을 생성하고 싶습니다.


diff (1)은 답이 아니지만 comm (1)입니다.

NAME
       comm - compare two sorted files line by line

SYNOPSIS
       comm [OPTION]... FILE1 FILE2

...

       -1     suppress lines unique to FILE1

       -2     suppress lines unique to FILE2

       -3     suppress lines that appear in both files

그래서

comm -2 -3 file1 file2 > file3

입력 파일을 정렬해야합니다. 그렇지 않은 경우 먼저 정렬하십시오. 이것은 임시 파일로 수행하거나 ...

comm -2 -3 <(sort file1) <(sort file2) > file3

쉘이 프로세스 대체를 지원한다면 (bash는).


유닉스 유틸리티 diff는이 목적을위한 것입니다.

$ diff -u file1 file2 > file3

옵션, 다른 출력 형식 등에 대해서는 설명서와 인터넷을 참조하십시오.


이것을 고려하십시오 :
파일 a.txt :

abcd
efgh

파일 b.txt :

abcd

다음과 같은 차이점을 찾을 수 있습니다.

diff -a --suppress-common-lines -y a.txt b.txt

출력은 다음과 같습니다.

efgh 

다음을 사용하여 출력 파일 (c.txt)로 출력을 다시 작성할 수 있습니다.

diff -a --suppress-common-lines -y a.txt b.txt > c.txt

이것은 귀하의 질문에 대답합니다 :

"... file2에없는 file1의 행을 포함합니다."


때로는 diff필요한 유틸리티가 필요하지만 때로는 join더 적합합니다. 파일을 미리 정렬해야하거나 bash, ksh 또는 zsh와 같은 프로세스 대체를 지원하는 쉘을 사용하는 경우 즉시 정렬 할 수 있습니다.

join -v 1 <(sort file1) <(sort file2)

시험

sdiff file1 file2

그것은 나를 위해 대부분의 경우 일반적으로 훨씬 잘 작동합니다. 행 순서가 중요하지 않은 경우 파일을 먼저 정렬 할 수 있습니다 (예 : 일부 텍스트 구성 파일).

예를 들어

sdiff -w 185 file1.cfg file2.cfg

coreutils 로이 문제를 해결 해야하는 경우 허용되는 대답은 좋습니다.

comm -23 <(sort file1) <(sort file2) > file3

정렬 또는 프로세스 대체가 필요하지 않고 무한 스트림을 지원 하는 sd (stream diff)를 사용할 수도 있습니다 .

cat file1 | sd 'cat file2' > file3

아마도이 예에서 그다지 큰 이점은 아니지만 여전히 고려해보십시오. 어떤 경우에는 commnor grep -F또는 을 사용할 수 없습니다 diff.

Here's a blogpost I wrote about diffing streams on the terminal, which introduces sd.


Many answers already, but none of them perfect IMHO. Thanatos' answer leaves some extra characters per line and Sorpigal's answer requires the files to be sorted or pre-sorted, which may not be adequate in all circumstances.

I think the best way of getting the lines that are different and nothing else (no extra chars, no re-ordering) is a combination of diff, grep, and awk (or similar).

If the lines do not contain any "<", a short one-liner can be:

diff urls.txt* | grep "<" | sed 's/< //g'

but that will remove every instance of "< " (less than, space) from the lines, which is not always OK (e.g. source code). The safest option is to use awk:

diff urls.txt* | grep "<" | awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}'

This one-liner diffs both files, then filters out the ed-style output of diff, then removes the trailing "<" that diff adds. This works even if the lines contains some "<" themselves.


Use the Diff utility and extract only the lines starting with < in the output


diff a1.txt a2.txt | grep '> ' | sed 's/> //' > a3.txt

I tried almost all the answers in this thread, but none was complete. After few trails above one worked for me. diff will give you difference but with some unwanted special charas. where you actual difference lines starts with '> '. so next step is to grep lines starts with '> 'and followed by removing the same with sed.


Yet, no grep solution?

  • lines which are exist only in file2:

    grep -Fxvf file1 file2 > file3
    
  • lines which are exist only in file1:

    grep -Fxvf file2 file1 > file3
    
  • lines which are exist in both files:

    grep -Fxf file1 file2 > file3
    

You could use diff with following output formatting:

diff --old-line-format='' --unchanged-line-format='' file1 file2

--old-line-format='' , disable output for file1 if line was differ compare in file2.
--unchanged-line-format='', disable output if lines were same.


I'm surprised nobody mentioned diff -y to produce a side-by-side output, for example:

diff -y file1 file2 > file3

And in file3(different lines have a symbol | in middle):

same     same
diff_1 | diff_2

참고URL : https://stackoverflow.com/questions/4544709/compare-two-files-line-by-line-and-generate-the-difference-in-another-file

반응형