Bash에서 Dejoin 또는 Reverse Join을 수행하는 방법

Bash에서 Dejoin 또는 Reverse Join을 수행하는 방법

일부 데이터 분석 소프트웨어에서 안티 조인(anti-join)이라고 부르는 작업을 수행하고 싶습니다. 즉, 한 목록에서 다른 목록의 행과 일치하는 행을 제거하는 것입니다. 다음은 일부 장난감 데이터와 예상 결과입니다.

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

답변1

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

답변2

유틸리티를 사용하여 이를 수행하는 한 가지 방법은 다음 join과 같습니다.

$ join -v 1 list1 list2
a
b

맨페이지에서:

-ㅏ파일 번호

: 또한 FILENUM 파일에서 페어링할 수 없는 줄을 인쇄합니다. 여기서 FILENUM은 FILE1 또는 FILE2에 해당하는 1 또는 2입니다.

-V파일 번호

: 좋다-ㅏFILENUM, 그러나 연결된 출력 라인을 억제합니다.

답변3

사용행복하다(이전 Perl_6)

Raku에는 Set단일 파일에서 읽어 다음 줄에서 컬렉션을 생성할 수 있는 개체 유형이 있습니다.

~$ raku -e 'my $a = Set.new: "list1".IO.lines; 
            my $b = Set.new: "list2".IO.lines; 
            say "list1 = ", $a;
            say "list2 = ", $b;'
list1 = Set(a b c d)
list2 = Set(c d e f)

ASCII 중위 또는 유니코드 중위를 사용하여 (-)비대칭 집합 차이를 수행 할 수 있습니다 .

~$ raku -e 'my $a = Set.new: "list1".IO.lines; 
            my $b = Set.new: "list2".IO.lines; 
            say $a (-) $b;'
Set(a b)
~$ raku -e 'my $a = Set.new: "list1".IO.lines; 
            my $b = Set.new: "list2".IO.lines; 
            say $b (-) $a;'
Set(e f)

OTOH, 가끔은 해야 할 일이 있어요대칭차이를 설정하면 Raku가 귀하의 필요에 적합합니다. ASCII 중위 (^)또는 유니코드 중위를 사용하십시오 .

~$ raku -e 'my $a = Set.new: "list1".IO.lines; 
            my $b = Set.new: "list2".IO.lines; 
            say $a (^) $b;'
Set(a b e f)

마지막으로 마지막 줄을 ... 로 변경하여 한 줄씩 출력할 수 있습니다 .keys.put for.
결정적인대칭다음은 유니코드 중위 연산자를 사용하여 차이를 설정하는 예입니다 .

~$ raku -e 'my $a = Set.new: "list1".IO.lines;
            my $b = Set.new: "list2".IO.lines;
            .keys.put for $a ⊖ $b;'
f
e
a
b

https://docs.raku.org/type/Set
https://docs.raku.org/언어/setbagmix#Operators_with_set_semantics
https://raku.org

관련 정보