파이프 구분 파일에서 5번째 열과 일치하는 항목 찾기

파이프 구분 파일에서 5번째 열과 일치하는 항목 찾기
File 1:
Connect|20130320000023|UTC|PPP|[email protected]|[email protected]|0BCBE578|
File 2:
Connect|20130320000023|UTC|PPP|[email protected]|[email protected]|0BCBE578|
Connect|20130320000025|UTC|PPP|[email protected]|[email protected]|0BCBE578|
Connect|20130320000025|UTC|PPP|[email protected]|[email protected]|0BCBE578|

열 5의 File 1과 File 2 모두에서 일치하는 레코드를 찾아야 합니다. 따라서 위에서 출력을 반환해야 합니다.

Connect|20130320000025|UTC|PPP|[email protected]|[email protected]|0BCBE578|

많은 감사를 드립니다.

답변1

방법 #1: grep & awk

이 코드 조각을 사용하여 이를 수행할 수 있습니다.

$ grep -f <(awk -F '|' '{print $5}' file1)  file2
Connect|20130320000025|UTC|PPP|[email protected]|[email protected]|0BCBE578|

세부

를 사용하는 비트는 awk첫 번째 파일을 구문 분석하여 file15번째 열을 모두 꺼냅니다. 그런 다음 이러한 값은 에 대한 목록으로 사용되며 grep일치하는 항목이 포함된 두 번째 파일의 모든 줄을 인쇄합니다.

이 방법의 주의사항

file1이 방법 은 의 5번째 열과 일치합니다 file2.

방법 #2: 그냥 어이없어

과거 현장에서 사용된 또 다른 접근 방식은 awk의 FNR 시설을 이용하는 것입니다. 여기에서는 awk첫 번째 파일의 각 줄에 대해 두 번째 파일을 한 줄씩 반복하면서 2개의 파일을 반복합니다.

이와 같은 접근 방식이 가능합니다. 다음을 파일에 넣으십시오 cmds.awk.

FNR == NR {
f1[$5] = $5
next
}

{ if ($5 == f1[$5]) print $0; }

그런 다음 다음과 같이 실행할 수 있습니다.

$ awk -F '|' -f cmds.awk file1 file2

메모:대신 이 패턴을 사용할 수도 있습니다 awk.

FNR == NR {
f1[$5] = $5
next
}

{ if ($5 in f1) print $0; }

$ awk -F '|' -f s.awk file1 file2
Connect|20130320000025|UTC|PPP|[email protected]|[email protected]|0BCBE578|

이 방법의 주의사항

이 접근 방식은 에서 각 이메일 주소의 단일 인스턴스만 처리할 수 있습니다 file1. 따라서 5번째 열에 대해 동일한 값을 갖는 두 줄이 있는 경우 이를 구별할 수 없습니다. 그러나 OP의 요구 사항을 고려할 때 이는 허용 가능한 것 같습니다.

가입 및 정렬

또한 join및 를 사용하여 이 작업을 수행할 수도 있습니다 sort.

$ join -t '|' -j 5  <(sort -k5,5 file2) <(sort -k5,5 file1) | sed 's/||.*//'

구분 기호를 사용 |하고 정렬된 파일을 5번째 열에 결합합니다. 이 접근 방식은 file1및 의 일치 항목을 모두 인쇄하므로 두 번째 일치 항목을 끝에서 잘라내는 데 file2사용합니다 .sed

$ join -t '|' -j 5  <(sort -k5,5 file2) <(sort -k5,5 file1) | sed 's/||.*//'
[email protected]|Connect|20130320000025|UTC|PPP|[email protected]|0BCBE578

답변2

나는 모든 것을 Perl로 할 것입니다:

$ perl -F'\|' -ane '$k{$F[4]}++; print if $k{$F[4]}>1' file1 file2  
Connect|20130320000025|UTC|PPP|[email protected]|[email protected]|0BCBE578|
  • -a배열로 자동 필드 분할을 활성화합니다 @F.
  • -F'\|'-a에 대한 필드 구분 기호를 로 설정합니다 |.
  • 처리된 각 줄에 대해 5번째 필드( 0perl에서 배열 인덱스 시작)를 해시 키로 저장하고 $k{$F[4]}++해당 값을 1씩 증가시킵니다. 필드가 두 번째로 표시되면 해당 값은 2가 됩니다.
  • 스크립트는 두 파일( file1before file2)의 각 줄을 처리하고 5번째 필드가 이전에 표시된 경우, 즉 $k{$F[4]}1보다 큰 경우 해당 줄을 인쇄합니다.

이는 다섯 번째 열이 내에서 반복되지 않는다고 가정합니다.같은파일. 그렇지 않고 일부 열이 동일한 파일에서 중복될 수 있는 경우 대신 다음을 사용하십시오.

perl -e 'open(A,"$ARGV[0]"); while(<A>){@F=split(/\|/);$k{$F[4]}++;}
         open(B,"$ARGV[1]"); while(<B>){@F=split(/\|/); print if $k{$F[4]} 
         }' file1 file2 

답변3

파일 크기가 비슷한 경우 최적의 솔루션은 다음과 같습니다.sort관심 있는 열을 기준으로 두 파일을 모두 선택한 다음join그 열 옆에 있습니다. 파일 크기가 이고 N점근 M적 런타임은 O(N*log(N)+M*log(M)).

파일 중 하나가 다른 파일보다 훨씬 작으면 O(N*M)다른 답변의 솔루션이 더 좋습니다.

관련 정보