Bash에서 anti-join 또는 inverse join을 수행하는 방법

일부 데이터 분석 소프트웨어에서 anti-join이라고 부르는 작업을 수행하고 싶습니다. 다른 목록에서 일치하는 줄. 다음은 장난감 데이터와 예상 출력입니다.

$ echo -e "a\nb\nc\nd" > list1 $ echo -e "c\nd\ne\nf" > list2 $ antijoincommand list1 list2 a b 

댓글

  • 관련 unix.stackexchange.com/q/11343/117549
  • 질문에 대한 답변이 되었습니까? 한 파일에서 다른 파일에없는 줄을 가져 오는 도구가 있습니까?
  • @Muru, 예, 해당 게시물이 솔루션을 제공합니다. Terdon '의 답변에 표시됩니다. 그러나 " bash anti-join " (이런 종류의 프로세스와 관련된 용어)을 검색 할 때 저는 ' 유용한 것을 찾지 못했습니다. 내 OP (다른 사람이 편집 한)는이 질문을하는 나의 명시적인 목적이 " 안티 조인 " 용어를 이 용어를 검색하면 이러한 솔루션이 생성됩니다. 감사합니다.

답변

join를 사용하지 않겠습니다. join는 입력을 정렬해야하기 때문에 이러한 간단한 작업에는 불필요한 복잡함이 발생합니다. 대신 grep를 사용할 수 있습니다.

$ grep -vxFf list2 list1 a b 

또는 awk :

$ awk "NR==FNR{++a[$0]} !a[$0]" list2 list1 a b 

파일이 이미 정렬 된 경우 join -v 1 대신 comm -23

$ comm -23 list1 list2 a b 

댓글

  • grepsort를 피하는 것이 좋습니다. 내가 제공 한 장난감 데이터에 대해 감사합니다. 실제로 내 file1에는 종종 여러 데이터 열이 있으며이 중 하나는 조인에 사용됩니다. awk의 수정 된 버전 코드가이 사용 사례를 해결합니다.
  • @Josh 예, $N를 사용하여 $0를 변경하면됩니다. N는 조인 할 필드 번호입니다.
  • 이것은 file1과 file2의 열 번호가 다른 경우에도 작동합니다. 예 : awk ' NR == FNR {++ a [$ 2]}! a [$ 5] ' list2 list1; 태그 파일의 형식이 기본 데이터와 다른 경우는 매우 일반적입니다.

답변

join 유틸리티를 사용하면 다음과 같습니다.

$ join -v 1 list1 list2 a b 

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다