파일이 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 답변! 이것은 순수한 집합 비교이기 때문에 실제로 아무것도 정렬할 필요가 없습니다.
입력 파일은 요소가 쌍으로 구성된 집합을 나타냅니다. 예를 들어 에서 줄이 foo
3번 나타나면 file1
< , 3> 요소를 의미합니다 foo
. 3번 file2
포함되면 두 foo
세트 모두 해당 요소를 포함한다는 의미입니다. 반복 횟수가 다르거나 포함 file2
되지 않은 경우 세트에 <, 3>이 포함되어 있지 않음 을 의미합니다 .foo
foo
foo
또한 <, 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"; }