첫 번째 열의 일치하는 값을 기준으로 파일 열의 값을 바꿉니다.

첫 번째 열의 일치하는 값을 기준으로 파일 열의 값을 바꿉니다.

질문이 있어요첫 번째 열의 값이 일치하면 file1의 두 열 값 중 일부를 file2의 값으로 바꿉니다.

예는 다음과 같습니다.

나는 가지고있다:

  • file1
    
    A 2012 3
    B 2012 4
    C 2012 9
    D 2012
    E 2012 7
    F 2012 
    
  • file2
    
    D 2007 12
    F 2009 8 
    G 2000 4
    

원하는 출력은 열 1의 값이 일치할 때입니다. 다음과 같이 열 2와 3의 값을 file2의 값으로 바꾸려고 합니다.

  • 원하는 출력:
    
    A  2012  3 
    B  2012  4  
    C  2012  9 
    D  2007  12
    E  2012  7  
    F  2009  8  
    

이 코드를 사용했는데 코드에 문제가 있다는 것을 알고 있습니다.

 awk 'BEGIN{FS=",";OFS="\t"}
    FNR==NR{a[$1]=$2;b[$1]=$3; next}
    FNR>=1{if(a[$1]){print $0 }else{print $1, a[$1], b[$1] }}
    ' file2 file1

이 코드를 사용할 때 내가 얻는 결과는 다음과 같습니다.

A  2012  3 
B  2012  4  
C  2012  9 
D  2012    
E  2012  7  
F  2012     

이는 와 동일합니다 file1.

누군가 이 코드의 문제점을 설명하거나 대체 솔루션을 제안할 수 있습니까?

답변1

문제에는 두 가지 측면이 있습니다.

  • 먼저 입력 필드 구분 기호를 로 설정하고 ,입력을 공백으로 구분하도록 선언합니다. 그러면 현장 작업이 제대로 작동하지 않습니다. 입력이 공백으로 구분된 경우 입력 줄은 기본적으로 "공백"(즉, 직접 연속되는 공백 및 탭의 수)으로 분할되므로 실제로 FS설정할 필요가 없습니다 .awk
  • 두 번째 문제는 귀하의 상황에 있습니다 if (a[$1]). 현재 행의 첫 번째 열 값이 file1에도 있는 경우 이는 정확하지만 코드에서는 실제로 원하는 값을 file2바꾸는 대신 변경되지 않은 행을 인쇄하게 됩니다 .file1file2
  • print $0또한 필드 구분 기호가 에서 읽은 것과 동일한 입력 줄을 인쇄하는 명령을 사용하여 해당 줄을 file1무시합니다 .OFS="\t"

대신 다음을 사용하세요.

awk 'BEGIN{OFS="\t"}
     NR==FNR{col2[$1]=$2;col3[$1]=$3;next}
     FNR>=1{if ($1 in col2) {$2=col2[$1];$3=col3[$1]} else {$1=$1}}1' file2 file1

공백이 올바르게 대체되도록 실제 출력 필드 구분 기호를 사용하여 행을 다시 작성 $1=$1하게 됩니다 .awk\t

관련 정보