두 파일의 내용을 비교하는 AWK 스크립트

두 파일의 내용을 비교하는 AWK 스크립트

파일이 2개 있어요..

파일 1:

abc|123|check
def|456|map
ijk|789|globe
lmn|101112|equator

파일 2:

check
map
equator
globe 

AWK 함수는 file1의 세 번째 열(세 번째 열을 자르고 정렬한 후)을 file2의 정렬된 내용과 비교해야 합니다.

  • 모든 행이 일치하면 1이 반환되어야 합니다.
  • 그렇지 않으면 2를 반환해야 합니다.

답변1

function are_all_there {
    local num_diff=$(comm -3 <(cut -d'|' -f3 "$1" | sort) <(sort "$2") | wc -l)
    (( num_diff == 0 )) && return 1 || return 2
}

답변2

awk귀하의 의견에 따르면 이것이 유일한 선택은 아닌 것 같습니다 . 따라서 이것은 awk가 아닌 방법입니다.
당신은 필요성을 언급하지 않았습니다고유한질문에서는 비교했지만 uniq주석의 예에서는 사용했습니다. 필요하지 않다면고유한일치하는 경우 정렬 옵션을 제거하면 됩니다 -u. (에서 테스트됨 bash).

(($(comm -3 <( cut -d'|' -f3 file1 | sort -u ) \
            <( sort -u file2 ) | wc -l))) && echo 2 - not all match ||
                                             echo 1 - all match

또는 awk-in 을 사용하여 최종 비교를 수행합니다 paste.

paste <( cut -d'|' -f3 file1 | sort -u ) \
      <( sort -u file2 ) |
   awk '$1!=$2{m=2; exit} 
     END{ if(m == 2){print "2 - not all match"; exit;} 
                     print "1 - all match";}' 

또는,awk 두 개의 입력 파일 비교

 awk '{if(NR == FNR){a[NR]=$1}
       else{ if($1 != a[NR]){m=2; exit}}}  
      END{ if(m == 2){print "2 - not all match"; exit;} 
                      print "1 - all match";}' \
    <( cut -d'|' -f3 file1 | sort -u ) \
    <( sort -u file2 ) |

답변3

흥미로운 CS 답변! 이것은 순수한 집합 비교이기 때문에 실제로 아무것도 정렬할 필요가 없습니다.

입력 파일은 요소가 쌍으로 구성된 집합을 나타냅니다. 예를 들어 에서 줄이 foo3번 나타나면 file1< , 3> 요소를 의미합니다 foo. 3번 file2포함되면 두 foo세트 모두 해당 요소를 포함한다는 의미입니다. 반복 횟수가 다르거나 포함 file2되지 않은 경우 세트에 <, 3>이 포함되어 있지 않음 을 의미합니다 .foofoofoo

또한 <, 3>과 같은 쌍 세트는 키를 3에 foo매핑하는 해시로 표시될 수 있습니다 .foo

TXR Lisp awk 매크로:

(awk (:begin (set fs "|"))
     (:let (h1 (hash :equal-based)) (h2 (hash :equal-based)))
     ((= arg 1) (inc [h1 [f 2] 0]))
     ((= arg 2) (inc [h2 rec 0]))
     (:end (exit (equal h1 h2))))

파일이 원하는 방식으로 동일하면 성공적인 종료 상태가 생성되고, 그렇지 않으면 실패 상태가 생성됩니다.

$ txr comp.tl 파일 1 파일 2
$에코$?
0
$에코 매핑>>파일2
$ txr comp.tl 파일 1 파일 2
$에코$?
1

"1" 또는 "2" 출력을 구문 분석하여 호출자를 복잡하게 만들려면 규칙을 변경하면 됩니다 :end.

(:end (prn (if (equal h1 h2) "1" "2")))

이것은 일반 awk의 경우입니다. 주요 차이점은 간결한 구문이 있고 참조하는 변수를 정의할 필요가 없다는 것입니다. 반면에 두 개의 연관 배열을 비교하고 추적할 자체 arg변수를 생성하기 위해 한 쌍의 루프를 작성해야 합니다. 우리가 작업 중인 파일 중 (GNU Awk는 ARGIND이러한 목적에 유용합니다 .)

BEGIN { FS = "|" }
FNR == 1 { arg++ }
arg == 1 { h1[$3]++; }
arg == 2 { h2[$0]++; }
END { same = 1
      for (i in h1)
        if (h1[i] != h2[i]) {
          same = 0
          break
        }
      if (same)
        for (i in h2)
          if (h2[i] != h1[i]) {
            same = 0
            break
          }
      print same ? "1" : "2"; }

관련 정보