두 개의 큰 파일의 차이점

두 개의 큰 파일의 차이점

"test1.csv"가 있는데 여기에는 다음이 포함되어 있습니다.

200,400,600,800
100,300,500,700
50,25,125,310

test2.csv 및 여기에는 다음이 포함됩니다.

100,4,2,1,7
200,400,600,800
21,22,23,24,25
50,25,125,310
50,25,700,5

지금

diff test2.csv test1.csv > result.csv

와는 다르다

diff test1.csv test2.csv > result.csv

어느 것이 올바른 순서인지는 모르겠지만 다른 것을 원합니다. 위의 두 명령 모두 다음과 같이 출력됩니다.

2 > 100,4,2,1,7
   3 2,3c3,5
   4 < 100,300,500,700
   5 < 50,25,125,310
   6 \ No newline at end of file
   7 ---
   8 > 21,22,23,24,25
   9 > 50,25,125,310

차이점만 출력하고 싶으므로 results.csv는 다음과 같아야 합니다.

100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5

나는 노력했지만 diff -q그들은 diff -s트릭을 수행하지 않았습니다. 순서는 중요하지 않습니다. 중요한 것은 >도 <도 공백도 없이 차이점만 보고 싶다는 것입니다.

grep -FvF큰 파일이 아닌 작은 파일에 대한 트릭을 수행했습니다.

첫 번째 파일에는 500만 개 이상의 줄이 포함되어 있고 두 번째 파일에는 1300줄이 포함되어 있습니다.

따라서 results.csv는 ~4,998,700줄이 되어야 합니다.

나는 또한 grep -F -x -v -f 작동하지 않는 것을 시도했습니다.

답변1

다음과 같은 직업인 것 같습니다 comm.

$ comm -3 <(sort test1.csv) <(sort test2.csv)
100,300,500,700
    100,4,2,1,7
    21,22,23,24,25
    50,25,700,5

설명된 대로 man comm:

   -1     suppress column 1 (lines unique to FILE1)

   -2     suppress column 2 (lines unique to FILE2)

   -3     suppress column 3 (lines that appear in both files)

즉, -3파일 중 하나에 고유한 줄만 인쇄된다는 의미입니다. 그러나 해당 항목은 발견된 파일에 따라 들여쓰기됩니다. 탭을 제거하려면 다음을 사용하십시오.

$ comm -3 <(sort test1.csv) <(sort test2.csv) | tr -d '\t'
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5

이 경우 파일을 정렬할 필요조차 없으며 위의 내용을 다음과 같이 단순화할 수 있습니다.

comm -3 test1.csv test2.csv | tr -d '\t' > difference.csv

답변2

프로세스 대체 grep와 함께 사용 :bash

$ cat <(grep -vFf test2.csv test1.csv) <(grep -vFf test1.csv test2.csv)
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5

출력을 다음과 같이 저장하려면 results.csv:

cat <(grep -vFf test2.csv test1.csv) <(grep -vFf test1.csv test2.csv) >results.csv
  • <()bash프로세스 대체 패턴

  • grep -vFf test2.csv test1.csv유일한 줄을 찾을 것입니다test1.csv

  • grep -vFf test1.csv test2.csv유일한 줄을 찾을 것입니다test2.csv

  • 마지막으로 결과를 요약하자면cat

아니면올리가 제안했어요, 명령 그룹화를 사용할 수도 있습니다.

$ { grep -vFf test2.csv test1.csv; grep -vFf test1.csv test2.csv; }
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5

또는 둘 다 STDOUT에 쓰고 있으므로 차례로 실행하면 최종적으로 추가됩니다.

$ grep -vFf test2.csv test1.csv; grep -vFf test1.csv test2.csv
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5

답변3

행 순서가 관련이 없으면 awk또는 다음을 사용하십시오 perl.

awk '{seen[$0]++} END {for (i in seen) {if (seen[i] == 1) {print i}}}' 1.csv 2.csv

grep공통 라인을 가져와서 필터링하려면 다음을 사용하세요 .

grep -hxvFf <(grep -Fxf 1.csv 2.csv) 1.csv 2.csv

내부 grep은 공통 라인을 얻은 다음 외부 grep은 이러한 공통 라인과 일치하지 않는 라인을 찾습니다.

답변4

순서를 유지할 필요가 없으므로 간단히 다음과 같이 하십시오.

sort test1.csv test2.csv | uniq -u
  • sort test1.csv test2.csv: 병합 및 test1.csv정렬test2.csv
  • uniq -u: 중복된 내용이 없는 줄만 인쇄합니다.

관련 정보