유닉스에서 두 개의 CSV 파일 사이의 헤더를 확인하는 방법은 무엇입니까?

유닉스에서 두 개의 CSV 파일 사이의 헤더를 확인하는 방법은 무엇입니까?
File1 - filename.csv
File2 - filename.csv

ksh 스크립트를 사용하여 Linux에서 이 두 파일 간의 헤더를 비교하고 싶습니다.

사례 1:-

예를 들어, file1의 헤더는 INPUT -->입니다.

NAME,UNIT CODE, VAR
JAMES01,IPU UNIT,OTHER
FIERCY,AUTOIMMUNE,OTHER

file2의 헤더는 INPUT입니다. -->

출력:- 이 두 파일 간의 헤더 일치

사례 2:-

file1의 헤더가 INPUT --> plant, 동물, object이고 file2의 헤더가 INPUT --> plant, 동물, object, tree라고 가정합니다.

출력 - 추가 열이 있습니다. EXCESS COLUMN NAME IS 'tree'

참고 - 헤더는 하드코딩되지 않고 csv 파일에서 가져옵니다. 매우 감사합니다!

답변1

가장 간단한 방법은 각 파일의 첫 번째 줄을 비교하고 동일한지 여부에 따라 올바른 디렉터리로 이동하는 것입니다.

$ diff -qs <(head -n1 file1.csv) <(head -n1 file2.csv) 
Files /dev/fd/63 and /dev/fd/62 differ

&&그런 다음 (and) 및 ||(or) 연산자를 사용하여 결과에 따라 파일에 대해 다양한 작업을 수행할 수 있습니다. 예를 들어 file2.csv동일한 헤더가 있으면 이름이 디렉터리로 이동하고 same, 다를 경우 이름이 디렉터리로 이동합니다 different.

$ mkdir -p same different
$ diff -qs <(head -n1 file1.csv) <(head -n1 file2.csv) && 
   mv file2.csv same/ || mv file2.cxv different/

어떤 특정 필드가 다른지 정말로 알아야 하고 차이가 항상 마지막 필드인지 확신할 수 있는 경우 다음을 수행할 수 있습니다.

diff -qs <(head -n1 file1.csv) <(head -n1 file2.csv) >/dev/null && 
   echo "The headers are the same" ||
   echo "file2.csv has an extra entry: $(awk -F, '{ print $NF; exit}' file2.csv)"

처리가 필요한 경우어느차이점, 사용:

awk -F, 'BEGIN{ FS=OFS="," }
       { 
        if(NR==FNR){ 
          for(i=1; i<=NF; i++){ a[$i]++ }
        }
        else{ 
         for(i=1; i<=NF; i++){ 
          if (! ($i in a)){
            b[$i]++
          }
         }
        }
       }
       END{ 
            printf "The second file has extra fields: ";
            for( field in b){
                printf "\"%s\" ", field
           }
       }' file1.csv file2.csv

답변2

nextfile이는 아마도 테스트되지 않은 상태에서 GNU awk와 같은 지원되는 awk를 사용하여 수행하려는 작업일 것입니다 .

awk '
    BEGIN { FS="," }
    FILENAME == ARGV[1] {
        nf = split($0,a)
        nextfile
    }
    FILENAME == ARGV[2] {
        nf = (NF > nf ? NF : nf)
        for ( i=1; i<=nf; i++ ) {
            if ( $i"" != a[i]"" ) {
                printf "Field %d difference: %s \"%s\" != %s \"%s\"\n", i, ARGV[1], a[i], FILENAME, $i
            }
        }
        exit
    }
' file1.csv file2.csv

귀하의 awk가 이를 지원하지 않는 경우 nextfile다음을 변경하십시오:

    FILENAME == ARGV[1] {
        nf = split($0,a)
        nextfile
    }

이와 관련하여:

    FILENAME == ARGV[1] {
        if ( NR == 1 ) {
            nf = split($0,a)
        }
        next
    }

여전히 작동하지만 첫 번째 줄뿐만 아니라 첫 번째 파일 전체를 읽어야 하기 때문에 느리게 실행됩니다.

위의 내용에서는 두 번째 파일이 비어 있지 않다고 가정합니다. 가능하다면 FILENAME == ARGV[2]해당 위치에서 두 번째 배열을 채우고 END해당 섹션에서 비교하십시오.

관련 정보