2016-10-22 8 views
1

해당 행과 열의 수가 같은 두 개의 대형 (예 : 300,000 * 100) 직사각형 CSV 파일이 있습니다. 두 파일의 각 해당 셀 사이에 차이가 있는지 찾아야합니다. 프로그램은 서로 다른 행과 셀 번호와 다른 내용을 o/p해야합니다.2 csv 파일의 차이점을 효율적으로 찾는 방법

행/열의 수가 매우 많기 때문에 가장 효율적인 방법을 찾고 있습니다.

가 처음에 내가 AWK와 함께 탐험을 시작하고, this 유망 보였지만, 내가 전에 AWK와 함께 일하지 않은 100 열 대신 예를

다음과 같이 2이 연장에 실패했다, 내가 시도한 자바를 이용한 일종의 무차별 접근법 - 2 차원 배열로 파일을로드한다. 주어진 컬럼에서 각각 작동하는 100 개의 스레드를 초기화하고, 차이가 발견되면 각 스레드는 row, cell 및 diff 값을 HashMap (Key로 열 번호 포함)에 넣습니다. 배열로 두 번째 파일을 읽는 동안 비교하여 비교를 시도했지만 실제로 각 셀을 방문하고 있기 때문에 속도가 빠를 수는 없습니다 (비교를 완료하는 데 약 8 시간이 걸렸습니다)

' awk 또는 Java에서 m ok. 다른 완전히 다른 접근 방식을 사용할 수 있습니다.

+1

'diff'를 사용하여 파일의 차이점을 확인하는 것은 어떨까요? 출력은 파일에 저장되거나 스크립트에서 사용되어 더 이상 분석하고 적절한 조치를 취할 수 있습니다. –

+0

바로 이것이 현재 프로그램이하는 일입니다. diff는 단지 전체 줄을 출력하고, 많은 경우에 왼쪽 파일에서 10 줄, 오른쪽 파일에서 10 줄을 말한다. 따라서 수동으로 복사하여 각 열을 시각적으로 비교하고 비교해야합니다. 행의 90 %에는 약간의 차이가 있습니다. diff o/p가 꽤 큽니다. – Plaiska

+2

그리고 그것을 내보내는 것이 어떨까요? 완전히 그것의 기능으로 속도가 아니지만 일부 매트릭스 검색을 여러 탭에 적용 할 수 있으며 배경 색상을 변경할 수 있다고 생각하십니까? –

답변

3

awk the rescue!

그것은 awk

$ paste -d, file.1 file.2 | 
    awk -F, '{m=NF/2; for(i=1;i<=m;i++) if($i!=$(i+m)) print NR,i,$i,$(i+m)}' 

인쇄에서이 일을 생각할 필요 없다 불평등 한 셀의 값을 "행 번호 열 번호가 좌우". 당신이 행 번호 외에 키 열을 인쇄하려면

, 당신은 고려 쉽게

$ paste -d, file.1 file.2 | 
    awk -F, -v key=8 '{m=NF/2; 
        for(i=1;i<=m;i++) 
         if($i!=$(i+m)) print $key,NR,i,$i,$(i+m)}' 
+0

출력에서 ​​고정 열 (예 : 8 번째 열의 값)의 값을 o/p 할 수 있습니까? 이 특정 값은 행의 고유 한 키로 양쪽 모두에서 동일하게 보장됩니다. – Plaiska

+0

파일을 사용하여이 작업을 시도하는 경우 타이밍을 게시하십시오. 최소 1 분 정도면 안됩니다. – karakfa

+0

굉장 .. 완료하는 데 약 1.5 분이 걸렸습니다. 당연히 Java 버전에는 추가 출력이 있었지만 속도가 느려서 쓸모가 없었습니다. 이 대답을 수락합니다. 나는 내가 필요로하는 것을 얻기 위해 o/p와 더 일할 수 있어야한다. 감사 – Plaiska

1

뭔가를 추가 할 수 있습니다 : 그것은 이후 매우 빠른해야

$ cat file1 
1,2,aa 
1,2,3 
1,bb,3 
1,2,3 

$ cat file2 
1,2,cc 
1,2,3 
1,dd,3 
1,2,3 

$ diff file1 file2 | 
awk -F, ' 
    /^[0-9]/ { row=$0+0; next } 
    sub(/^< /,"") { split($0,a); next } 
    sub(/^> /,"") { for (col=1;col<=NF;col++) if ($col != a[col]) print row, col, a[col], $col } 
' 
1 3 aa cc 
3 2 bb dd 

만 awk를 실행하고 모든 라인이 아닌 차이가있는 라인에서 루프를 수행합니다.

1

univocity-parsers 'CSV 파서는이 문제를 처리 5 초보다 훨씬 더 오래 걸릴하지 않습니다

public void diff(File leftInput, File rightInput) { 
    CsvParserSettings settings = new CsvParserSettings(); //many config options here, check the tutorial 

    CsvParser leftParser = new CsvParser(settings); 
    CsvParser rightParser = new CsvParser(settings); 

    leftParser.beginParsing(leftInput); 
    rightParser.beginParsing(rightInput); 

    String[] left; 
    String[] right; 

    int row = 0; 
    while ((left = leftParser.parseNext()) != null && (right = rightParser.parseNext()) != null) { 
     row++; 
     if (!Arrays.equals(left, right)) { 
      System.out.println(row + ":\t" + Arrays.toString(left) + " != " + Arrays.toString(right)); 
     } 
    } 

    leftParser.stopParsing(); 
    rightParser.stopParsing(); 
} 

공시 :이 라이브러리의 저자입니다. 오픈 소스이며 무료입니다 (Apache V2.0 라이센스).

관련 문제