다른 파일을 사용하여 일치하는 열이 있는 파이프로 구분된 파일에서 줄을 삭제하는 Perl 스크립트

다른 파일을 사용하여 일치하는 열이 있는 파이프로 구분된 파일에서 줄을 삭제하는 Perl 스크립트

파이프()로 구분된 열의 ​​모든 레코드를 File A포함 하는 두 개의 거대한 파일이 있는데 그 파일에는 단 하나의 열만 있습니다.|File B

File A해당 열의 값이 일치하는 모든 행을 삭제해야 합니다 File B.

파일 B의 열 1을 파일 A의 열 2와 비교하고 싶습니다.

FileB - fileB의 유일한 열

818815504
842019301
880702511

FileA - FileA의 두 번째 열

2020-01-19|777504559|2|15|1|403941|53|4708267|3036|5033|127380343|0|3905585|C|1168|IRU|107|NR
2020-01-19|818815504|2|15|1|403933|8|2394063|3036|2394067|4076948618|0|15177438|B|1168|CRU|98|NK
2020-01-19|842019301|2|15|1|2|2|3712|3036|961249|65707843|65707843|8591573|B|1168|IRU|1|NJ
2020-01-19|847082255|2|15|1|2|2|284|3036|291|125650195|125650195|8870299|C|1168|IRU|1|NR
2020-01-19|858760375|2|15|1|403941|53|4708267|3036|306|99931425|0|8866849|C|1168|IRU|107|NR
2020-01-19|869323039|2|15|1|2|2|371|3036|307|106104029|106104029|4518435|C|1168|IRU|2|NR
2020-01-19|872268371|2|15|1|403941|53|4708267|3036|143|127382679|0|8866849|C|1168|IRU|107|NR
2020-01-19|858760375|2|15|1|2|2|117|3036|109|2739523|5208959|4037061|C|1168|IRU|2|NR

답변1

결과의 순서는 중요하지 않다고 가정합니다.

$ join -v 1 -t '|' -1 2 <( sort -t '|' -k2,2 fileA ) <( sort fileB )
777504559|2020-01-19|2|15|1|403941|53|4708267|3036|5033|127380343|0|3905585|C|1168|IRU|107|NR
847082255|2020-01-19|2|15|1|2|2|284|3036|291|125650195|125650195|8870299|C|1168|IRU|1|NR
858760375|2020-01-19|2|15|1|2|2|117|3036|109|2739523|5208959|4037061|C|1168|IRU|2|NR
858760375|2020-01-19|2|15|1|403941|53|4708267|3036|306|99931425|0|8866849|C|1168|IRU|107|NR
869323039|2020-01-19|2|15|1|2|2|371|3036|307|106104029|106104029|4518435|C|1168|IRU|2|NR
872268371|2020-01-19|2|15|1|403941|53|4708267|3036|143|127382679|0|8866849|C|1168|IRU|107|NR

join유틸리티는 지정된 두 데이터 세트에 대해 관계형 INNER JOIN 작업을 수행합니다. 데이터 세트는 우리가 조인하는 열을 기준으로 정렬되어야 하며, 이것이 호출하기 전에 파일을 정렬하는 이유입니다 join(쉘이 프로세스 대체를 지원하지 않는 경우 파일을 별도로 미리 정렬하십시오). join여기서 사용하는 옵션 -t '|'-1 2" |열 구분 기호로 사용하고 첫 번째 데이터 세트의 두 번째 열에 연결"을 의미합니다(그렇지 않으면 첫 번째 열이 기본값임).

우리는 -v 1두 번째 파일의 줄과 짝을 이룰 수 없는 첫 번째 파일의 모든 줄을 요청합니다.

출력에는 항상 조인 열이 먼저 나열되므로 처음 두 열을 다음과 바꿔서 올바른 위치로 이동할 수 있습니다 awk.

$ join -v 1 -t '|' -1 2 <( sort -t '|' -k2,2 fileA ) <( sort fileB ) | awk 'BEGIN { FS=OFS="|" } { t=$1; $1=$2; $2=t; print }'
2020-01-19|777504559|2|15|1|403941|53|4708267|3036|5033|127380343|0|3905585|C|1168|IRU|107|NR
2020-01-19|847082255|2|15|1|2|2|284|3036|291|125650195|125650195|8870299|C|1168|IRU|1|NR
2020-01-19|858760375|2|15|1|2|2|117|3036|109|2739523|5208959|4037061|C|1168|IRU|2|NR
2020-01-19|858760375|2|15|1|403941|53|4708267|3036|306|99931425|0|8866849|C|1168|IRU|107|NR
2020-01-19|869323039|2|15|1|2|2|371|3036|307|106104029|106104029|4518435|C|1168|IRU|2|NR
2020-01-19|872268371|2|15|1|403941|53|4708267|3036|143|127382679|0|8866849|C|1168|IRU|107|NR

다음만 사용하세요 awk:

$ awk -F '|' 'FNR==NR { key[$1]=1; next } !($2 in key)' fileB fileA
2020-01-19|777504559|2|15|1|403941|53|4708267|3036|5033|127380343|0|3905585|C|1168|IRU|107|NR
2020-01-19|847082255|2|15|1|2|2|284|3036|291|125650195|125650195|8870299|C|1168|IRU|1|NR
2020-01-19|858760375|2|15|1|403941|53|4708267|3036|306|99931425|0|8866849|C|1168|IRU|107|NR
2020-01-19|869323039|2|15|1|2|2|371|3036|307|106104029|106104029|4518435|C|1168|IRU|2|NR
2020-01-19|872268371|2|15|1|403941|53|4708267|3036|143|127382679|0|8866849|C|1168|IRU|107|NR
2020-01-19|858760375|2|15|1|2|2|117|3036|109|2739523|5208959|4037061|C|1168|IRU|2|NR

먼저 연관 배열로 추출하려는 숫자를 읽습니다 key. 그런 다음 두 번째 파일을 구문 분석할 때 두 번째 필드가 해당 배열의 키가 아닌 경우 해당 줄을 인쇄합니다.

이는 해당 파일에 나타나는 순서대로 행을 출력 fileA하지만 모든 숫자를 fileB메모리에 보관해야 한다는 단점이 있습니다.


요청에 따라 Perl을 사용하십시오.

$ perl -F'\|' -le 'if (!$flag){ $key{$F[0]}=1 } elsif ($key{$F[1]}!=1) { print $_ }; if (!$flag && eof) { $flag=1 };' fileB fileA
2020-01-19|777504559|2|15|1|403941|53|4708267|3036|5033|127380343|0|3905585|C|1168|IRU|107|NR
2020-01-19|847082255|2|15|1|2|2|284|3036|291|125650195|125650195|8870299|C|1168|IRU|1|NR
2020-01-19|858760375|2|15|1|403941|53|4708267|3036|306|99931425|0|8866849|C|1168|IRU|107|NR
2020-01-19|869323039|2|15|1|2|2|371|3036|307|106104029|106104029|4518435|C|1168|IRU|2|NR
2020-01-19|872268371|2|15|1|403941|53|4708267|3036|143|127382679|0|8866849|C|1168|IRU|107|NR
2020-01-19|858760375|2|15|1|2|2|117|3036|109|2739523|5208959|4037061|C|1168|IRU|2|NR

이는 프로그램을 모방 하지만 Perl에는 별도의 내장 변수 awk가 없기 때문에 현재 첫 번째 파일을 구문 분석하고 있는지 아니면 두 번째 파일을 구문 분석하고 있는지 알려주는 일부 상태( )를 유지해야 합니다 .NRFNR$flag

관련 정보