유닉스에서 열별로 파일 비교

유닉스에서 열별로 파일 비교

동일한 행과 열 수, 동일한 레코드 순서를 가진 두 파일을 비교하고 싶습니다. 열 값의 차이가 있는 경우 이를 강조하고 싶습니다.

file A:

1,kolkata,19,ab

2,delhi,89,cd

3,bangalore,56,ef

file B:

1,kolkata,21,ab

2,mumbai,89,gh

3,bangalore,11,kl

열을 1기본 키로 간주하면 다른 열과 차이점이 있습니다. 저는 이러한 차이점을 강조하고 싶습니다.

출력 형식은 다음과 같습니다(확실하지 않음).

record_number,  columns_with_diff
1               3

2               2,4

3               3,4

내 문제를 diff해결할 수 있나요 ? comm그렇다면 정확한 명령은 무엇입니까?

답변1

그게 다야. 각 줄 끝에 추가 쉼표가 있는 경우 몇 가지 스타일 문제가 있습니다.

awk '
     BEGIN{ FS=","; ORS="" }

     { 
       # read line from secondary file
       getline aux < "file2"
       split(aux,f2,",")

       # print current line number
       print NR" "

       # process each field in current line
       for(i=1; i<=NF; i++) {
         if ($i!=f2[i]) {
           print i","
         }
       }
       print "\n"
     }
' file1

산출:

1 3,
2 2,4,
3 3,4,

답변2

다음을 사용하면 이 작업을 더 쉽게 수행할 수 있습니다 perl.

$ perl -F',' -anle '
    BEGIN{
        print "record_number,  columns_with_diff";
        $" = ",";
    }
    if (!defined($h{$.})) {
        @{$h{$.}}{0..$#F} = @F[0..$#F];
    } else {
        @diff =  grep { $h{$.}{$_} ne $F[$_] } 0..$#F;
        print "$.\t\t@{[map {$_+1} @diff]}";
    } 
    close ARGV if eof;
' file1 file2
record_number,  columns_with_diff
1       3
2       2,4
3       3,4

이렇게 하려면 입력에서 빈 줄을 제거해야 합니다.

설명하다

  • 블록 에서는 BEGIN출력 제목을 인쇄한 다음 목록 구분 기호를 다음과 같이 설정합니다.,

  • @{$h{$.}}{0..$#F} = @F[0..$#F]: 해시의 해시를 생성합니다. 여기서 첫 번째 해시의 키는 행 번호이고, 각 하위 해시의 키는 필드 인덱스에서 1을 뺀 값이며, 값은 해당 필드에 해당하는 값입니다.

여기서는 해시 슬라이싱을 사용하여 해시의 해시에 값을 빠르게 할당합니다.

Data::Dumperhash 의 해시를 인쇄 하면 %h다음과 같은 내용을 볼 수 있습니다.

VAR1 = {
          '2' => {
                   '2' => '89',
                   '0' => '2',
                   '1' => 'delhi',
                   '3' => 'cd'
                 },
          '3' => {
                   '1' => 'bangalore',
                   '3' => 'ef',
                   '0' => '3',
                   '2' => '56'
                 },
          '1' => {
                   '3' => 'ab',
                   '1' => 'kolkata',
                   '0' => '1',
                   '2' => '19'
                 }
        };
  • %h( )를 생성하면 if (!defined($h{$.}))(처리가 완료되었음을 의미 file1) 현재 행의 각 필드를 의 핵심 값과 비교하여 %h모든 다른 인덱스를 배열에 저장합니다 @diff. map {$_+1} @diff배열 인덱싱은 0에서 시작하고 열 번호는 1에서 시작하므로 열 번호를 복구합니다.

  • close ARGV if eof카운터를 복원합니다 $..

관련 정보