열과 행 수가 다른 두 파일을 연결합니다.

열과 행 수가 다른 두 파일을 연결합니다.

두 개의 파일이 있습니다. file_1.txt는 다음과 같습니다:

R1     C1     C2     C3     C4     C5
R2     C1     C2     C3     C4     C5
R3     C1     C2     C3     C4     C5
R4     C1     C2     C3     C4     C5
R5     C1     C2     C3     C4     C5
R6     C1     C2     C3     C4     C5
R7     C1     C2     C3     C4     C5
R8     C1     C2     C3     C4     C5
R9     C1     C2     C3     C4     C5
R10    C1     C2     C3     C4     C5

file_2.txt는 다음과 같습니다:

R4 C4 C5
R6 C4 C5
R7 C4 C5
R9 C4 C5

file_1.txt의 C4, C5 값을 file_2.txt의 해당 값으로 바꾸고, file_1.txt의 C1, C2, C3 값은 그대로 유지하고 싶습니다.

따라서 생성된 file_3.txt는 다음과 같아야 합니다.

R1     C1     C2     C3     C4     C5
R2     C1     C2     C3     C4     C5
R3     C1     C2     C3     C4     C5
R4     C1     C2     C3     C4_new C5_new
R5     C1     C2     C3     C4     C5
R6     C1     C2     C3     C4_new C5_new
R7     C1     C2     C3     C4_new C5_new
R8     C1     C2     C3     C4     C5
R9     C1     C2     C3     C4_new C5_new
R10    C1     C2     C3     C4     C5

모든 값은 숫자입니다. file_1.txt 및 file_2.txt의 첫 번째 열은 숫자가 오름차순으로 정렬된 키 필드입니다.

이게 한 사람만 가입하면 할 수 있는 일인가요?

답변1

이 문제에 대한 일반적인 응용 프로그램은 다음과 같습니다.

awk 'NR == FNR{a1[$1]=$2; a2[$1]=$3; next};
    $1 in a1{$5=a1[$1]; $6=a2[$1]};{print}' file_2.txt file_1.txt     

출력 필드 구분 기호를 탭으로 명시적으로 설정해야 할 수도 있습니다. 이 경우

awk -v OFS='\t' 'NR == FNR{a1[$1]=$2; a2[$1]=$3; next};
    $1 in a1{$5=a1[$1]; $6=a2[$1]};{print}' file_2.txt file_1.txt 

답변2

이는 문제를 해결하지 못하지만 join명목상으로는 이 특별한 경우에 작동해야 하는 것처럼 들리지만 작동하지 않는 이유를 보여줍니다. 나는 join이 사이트에서 귀하와 유사한 문제를 해결하기 위해 꽤 많은 시간을 보냈습니다 .고유 식별자를 사용하여 두 파일 연결.

첫 번째 방법

귀하의 문제에 대한 해결책 join은 다음과 같습니다.

$ join -a1 -1 1 -2 1 -o 1.1 1.2 1.3 1.4 2.2 2.3 <(sort file_1.txt) <(sort file_2.txt)
R10 C1 C2 C3  
R1 C1 C2 C3  
R2 C1 C2 C3  
R3 C1 C2 C3  
R4 C1 C2 C3 C4_new C5_new
R5 C1 C2 C3  
R6 C1 C2 C3 C4_new C5_new
R7 C1 C2 C3 C4_new C5_new
R8 C1 C2 C3  
R9 C1 C2 C3 C4_new C5_new

보시다시피 join파일을 정렬된 형식으로 배치해야 하므로 우선 파일의 원래 순서가 중요한 경우 이 옵션을 사용하면 문제가 발생할 수 있습니다.

join또한 값, 값의 존재 또는 부재에 따라 한 파일 또는 다른 파일에서 열 값을 조건부로 인쇄할 수 있는 방법이 없습니다 .

두 번째 방법

또 다른 접근 방식 join은 다음과 같습니다.

$ join -a1 -1 1 -2 1  <(sort file_1.txt) <(sort file_2.txt)
R10 C1 C2 C3 C4 C5
R1 C1 C2 C3 C4 C5
R2 C1 C2 C3 C4 C5
R3 C1 C2 C3 C4 C5
R4 C1 C2 C3 C4 C5 C4_new C5_new
R5 C1 C2 C3 C4 C5
R6 C1 C2 C3 C4 C5 C4_new C5_new
R7 C1 C2 C3 C4 C5 C4_new C5_new
R8 C1 C2 C3 C4 C5
R9 C1 C2 C3 C4 C5 C4_new C5_new

다시 말하지만 이는 원하는 것과 비슷하지만 조건부 논리를 사용하여 한 파일 또는 다른 파일의 열을 인쇄하는 것을 허용하지 않습니다.

세 번째 방법

이것은 작동 하지만 awk.file_2.txt

$ join -a1 -1 1 -2 1 -o 1.1 1.2 1.3 1.4 2.2 2.3 1.5 1.6 1.7 <(sort file_1.txt) <(sort file_2.txt) | awk '{$7=$8=""}1'
R10 C1 C2 C3 C4 C5  
R1 C1 C2 C3 C4 C5  
R2 C1 C2 C3 C4 C5  
R3 C1 C2 C3 C4 C5  
R4 C1 C2 C3 C4_new C5_new  
R5 C1 C2 C3 C4 C5  
R6 C1 C2 C3 C4_new C5_new  
R7 C1 C2 C3 C4_new C5_new  
R8 C1 C2 C3 C4 C5  
R9 C1 C2 C3 C4_new C5_new  

방금 가입했습니까?

Join 시장은 매우 좁으며 유용한 도구가 될 수 있습니다. 대체 유형 질문(귀하의 질문이 더 적합한 경우)의 경우 awk, perl또는 같은 도구가 sed더 적합합니다.

관련 정보