두 열과 일치하고 일치하지 않는 두 파일을 연결하고 일치하는 각 줄에서 파일 1의 두 번째 열을 파일 2의 여섯 번째 열로 바꿉니다.

두 열과 일치하고 일치하지 않는 두 파일을 연결하고 일치하는 각 줄에서 파일 1의 두 번째 열을 파일 2의 여섯 번째 열로 바꿉니다.

저는 이 작업을 수행하려고 합니다.

두 개의 파일이 있습니다.
파일 1좋다:

102 13.342
103 7.456
105 6.453
107 3.567
108 4.210

파일 2좋다:

0 098 0 0 0 -9 x
0 099 0 0 0 -9 x
0 100 0 0 0 -9 x
0 101 0 0 0 -9 x
0 102 0 0 0 -9 x
0 103 0 0 0 -9 x
0 104 0 0 0 -9 x
0 105 0 0 0 -9 x
0 106 0 0 0 -9 x
0 106 0 0 0 -9 x
0 107 0 0 0 -9 x
0 108 0 0 0 -9 x

내가 하나를 원하는파일 3처럼 보인다

 0 098 0 0 0 -9 x
 0 099 0 0 0 -9 x
 0 100 0 0 0 -9 x
 0 101 0 0 0 -9 x
 0 102 0 0 0 13.342 x
 0 103 0 0 0 7.456 x
 0 104 0 0 0 -9 x
 0 105 0 0 0 6.453 x

기본적으로 file1과 file2의 첫 번째 및 두 번째 필드를 각각 일치시키고 일치하지 않는 항목을 유지하고 일치하는 각 줄에서 file1의 두 번째 필드 값을 file2의 두 번째 필드 값으로 대체하여 file1과 file2를 연결하려고 합니다. 여섯 번째 필드의 값입니다. ..

나는 이 작업이 다음을 사용하는 것과 관련되어 있다는 것을 알고 있습니다 join -a1 -a2 -o 1.2 whatsoever. 하지만 진행 방법을 알 수 없습니다... 또한 이상한 것으로 간주됩니다.

답변1

관련된 영역이 너무 많을 때 나는 다음을 선택하는 경향이 있습니다 awk.

$ awk 'NR==FNR{a[$1]=$2; next}{if($2 in a){$6=a[$2]}}1;' file1 file2 
0 098 0 0 0 -9 x
0 099 0 0 0 -9 x
0 100 0 0 0 -9 x
0 101 0 0 0 -9 x
0 102 0 0 0 13.342 x
0 103 0 0 0 7.456 x
0 104 0 0 0 -9 x
0 105 0 0 0 6.453 x
0 106 0 0 0 -9 x
0 106 0 0 0 -9 x
0 107 0 0 0 3.567 x
0 108 0 0 0 4.210 x

설명하다

  • NR==FNR{a[$1]=$2; next}: NR는 현재 줄 번호이고 FNR현재 파일의 현재 줄 번호입니다. 여러 파일을 처리할 때 첫 번째 파일을 읽는 경우에만 두 파일이 동일해집니다. 다음 파일 1을 a[$1]=$2사용하세요 .st field as a key to an array whose value is the 2nd field. Theskips to the next line. So, this will save all values frominto the array

  • if($2 in a){$6=a[$2]}: 이제 두 번째 파일을 읽고 있습니다. 행의 두 번째 필드가 배열에 있는 경우 a여섯 번째 필드( )는 $6두 번째 필드에 저장된 항목으로 설정됩니다.a

  • 1;: "이 줄을 인쇄하세요"의 줄임말입니다.

답변2

두 파일 모두 키 필드(보통 6번째 필드 -9) 를 기준으로 정렬된 경우

join -1 2 -a 1 -e '-9' -o 1.1 1.2 1.3 1.4 1.5 2.2 1.7 file2 file1

작업을 완료했습니다(감사합니다.강철 드라이버수정을 위해)
그러나 더 정확한 것은sed` 형식:

join -1 2 -a 1 2 1 -o 1.1,1.2,1.3,1.4,1.5,1.6,2.2,1.7 |
sed 's/ \S*\( \S\+\)/\1/3'

너가 선호한다면file1다음 키가 모두 있는지 확인하세요 .file2

awk '{
    a=0
    do {
        if (a)
           print a
        getline a <"file2"
        split(a,A)
        }
    while($1 != A[2])
    i=0
    A[6]=$2
    for(i in A)
        printf("%s ",A[i++])
    print ""
    }' file1

관련 정보