파이프라인 구분 파일의 다섯 번째 열과 일치하는 항목 찾기

파이프라인 구분 파일의 다섯 번째 열과 일치하는 항목 찾기
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열의 file1과 file2에서 일치하는 레코드를 찾아야 합니다. 따라서 위에서 출력을 반환해야 합니다.

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첫 번째 파일을 구문 분석하고 file1다섯 번째 열을 모두 추출합니다. 그런 다음 이러한 값은 목록으로 사용되며 grep일치하는 항목이 포함된 두 번째 파일의 모든 줄을 인쇄합니다.

이 방법을 사용할 때 주의할 점

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

방법 #2: 그냥 어이없어

과거 이 현장에서 사용된 또 다른 방법은 awkFNR 시설을 이용하는 것입니다. 여기서는 awk2개의 파일을 반복하여 두 번째 파일을 한 줄씩 살펴보고 첫 번째 파일의 각 줄을 찾습니다.

이와 같은 것이 가능합니다. 다음 내용을 파일에 넣으십시오 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열에 같은 값의 행이 2개 있으면 구별할 수 없습니다. OP에서 요구하는 내용을 고려하면 이는 허용되는 것 같습니다.

가입 및 정렬

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

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

그러면 구분 기호가 사용되어 |정렬된 파일이 다섯 번째 열에 연결됩니다. 이 메소드는 file1sum 에서 일치 항목을 인쇄하므로 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번째 필드(Perl의 배열 인덱스에서 시작 0)를 해시 키로 저장 $k{$F[4]}++하고 해당 값을 1씩 증가시킵니다. 필드를 두 번째로 볼 때 값은 2가 됩니다.
  • 스크립트는 두 파일( file1before )의 각 줄을 처리하고 file25번째 필드가 이전에 표시된 경우, 즉 1보다 큰 경우 $k{$F[4]}해당 줄을 인쇄합니다 .

이는 다섯 번째 열이동일한문서. 그렇지 않고 일부 열이 동일한 파일에서 반복될 수 있는 경우 대신 다음 명령을 사용하십시오.

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)다른 답변의 솔루션이 더 좋습니다.

관련 정보