조인 가능한 각 f1 레코드가 f2에서 사용 가능한 첫 번째 일치 가능한 레코드에 한 번만 조인되도록 f1을 f2에 조인합니다.

조인 가능한 각 f1 레코드가 f2에서 사용 가능한 첫 번째 일치 가능한 레코드에 한 번만 조인되도록 f1을 f2에 조인합니다.

열 1과 열 2를 기준으로 정렬된 다음 두 파일이 있다고 가정합니다.

f1:

card1,value1,f1c11,f1c12
card2,value2,f1c21,f1c22
card3,value3,f1c31,f1c32
card4,value4,f1c41,f1c42
card4,value4,f1c411,f1c412
card4,value41,f1c421,f1c422
card5,vaule5,f1c51,f1c52

f2:

card,value2,f2c1,f2c2
card2,value,f2c21,f2c22
card2,value2,f2c211,f2c212
card2,value2,f2c221,f2c222
card3,value3,f2c31,f2c32
card4,value4,f2c41,f2c42
card4,value4,f2c411,f2c412
card5,vaule5,f2c51,f2c52
card6,vaule6,f2c61,f2c62
card7,vaule5,f2c71,f2c72

원하는 사항: f1을 f2에 조인하여 조인 가능한 각 f1 레코드가 f2에서 사용 가능한 첫 번째 일치 가능한 레코드에 한 번만 조인되도록 합니다.

card2,value2,f1c21,f1c22,f2c211,f2c212
card3,value3,f1c31,f1c32,f2c31,f2c32
card4,value4,f1c41,f1c42,f2c41,f2c42
card4,value4,f1c411,f1c412,f2c41,f2c42
card5,vaule5,f1c51,f1c52,f2c51,f2c52

자세한 매칭 로직은 다음과 같습니다.

  • f1의 카드1,값1(라인 1) f2에서 일치하는 항목이 표시되지 않음 -> 무시
  • f1(라인 2)의 card2,value2는 f2(라인 3)에서 첫 번째 일치를 확인합니다. 이 일치 후에는 f1 라인 2와 f2 라인 3을 더 이상 사용할 수 없습니다.
  • f1(라인 3)의 card3,value3은 f2(라인 5)에서 첫 번째 일치를 확인합니다. 이 일치 후 f1 라인 3과 f2 라인 5는 더 이상 사용할 수 없습니다.
  • f1(라인 4)의 card4,value4는 f2(라인 6)에서 첫 번째 일치를 확인합니다. 이 일치 후에는 f1 라인 4와 f2 라인 6을 더 이상 사용할 수 없습니다.
  • f1(라인 5)의 card4,value4는 f2(라인 7)에서 첫 번째 일치를 확인합니다. 이 일치 후에는 f1 라인 5와 f2 라인 7을 더 이상 사용할 수 없습니다.
  • f1의 카드4,값4(라인 6)는 f2에서 일치하는 항목을 찾지 못합니다. -> 무시
  • f1(라인 7)의 card5,value5는 f2(라인 8)에서 첫 번째 일치를 확인합니다. 이 일치 후에는 f1 라인 7 및 f2 라인 8을 더 이상 사용할 수 없습니다.

답변1

Bash와 GNU awk를 사용한 스크립팅. 이는 입력 파일 중 하나를 정렬할 필요가 없습니다. 출력은 인수로 전달된 첫 번째 파일의 순서대로 이루어집니다.

네 번째 출력 라인에 문제가 있는 것 같습니다. f2 카드4 첫 번째 라인이 다시 반복됩니다.

두 번째 파일의 전체 내용은 Row 배열에 저장되며, 행 번호는 입력된 순서대로 List 형태로 Map에 저장됩니다.

그런 다음 첫 번째 파일은 아무 것도 남지 않을 때까지 사용하는 모든 매핑 항목을 제거합니다.

#! /bin/bash --

#:: firstJoin: join only the first records with matching keys.

Join () {

    local AWK='
BEGIN { FS = ","; OFS = ","; reClip = "^[^,]*,[^,]*,"; }
#.. Store input from first file.
function Store (key, tx, Local) {
    sub (reClip, "", tx);
    Row[FNR] = tx;
    Map[key] = Map[key] FNR FS FS;
}
#.. Pair second file with first available.
function Pair (key, tx, Local) {
    if (! (key in Map) || (Map[key] == "")) return;
    printf ("%s%s%s\n", tx, OFS, Row[0+Map[key]]);
    sub (reClip, "", Map[key]);
}
FNR == NR { Store( $1 FS $2, $0); next; }
{ Pair( $1 FS $2, $0); }
'   
    awk -f <( printf '%s' "${AWK}" ) "${2}" "${1}"
}   
    
    Join "${1}" "${2}"

테스트 샷:

Paul--) ./firstJoin  JoinF1 JoinF2
card2,value2,f1c21,f1c22,f2c211,f2c212
card3,value3,f1c31,f1c32,f2c31,f2c32
card4,value4,f1c41,f1c42,f2c41,f2c42
card4,value4,f1c411,f1c412,f2c411,f2c412
card5,vaule5,f1c51,f1c52,f2c51,f2c52
Paul--) 

관련 정보