편집하다

편집하다

열이 탭으로 구분된 서로 다른 형식의 두 개의 파일이 있습니다. 의 열 을 와 column1비교 해야 합니다 . 일치하면 의 값을 의 값으로 바꿔야 합니다 . 사용해 보았으나 값을 대체할 수 없습니다. 아래 코드 조각에 대한 제안을 해주실 수 있나요?column2file1file2column6file1column3file2awk

awk 'FILENAME == ARGV[1] {
    m[$1,$2] = $6;
    next;
}
{
    if (($1,$2) in m) {
        m[$6]= $3; print m[$6];
    }
}' file1 file2


top few lines of file1
1201 12011 1 0 0 0 1
1202 12021 1 0 0 0 1
1203 12031 1 0 0 0 1
1204 12041 1 0 0 0 2
1207 12071 1 0 0 0 2
1209 12091 1 0 0 0 1
1210 12101 1 0 0 0 1
1212 12121 1 0 0 0 1
1213 12131 1 0 0 0 1
1214 12141 1 0 0 0 2

top few lines of file2
1201    12011   1
1202    12021   1
1203    12031   1
1204    12041   1
1206    NA  1
1207    12071   2
1208    NA  1
1209    12091   2
1210    12101   2

업데이트된 내용을 다른 파일에 쓰고 싶기 때문에 file2의 값을 file1 열에 할당하고 싶습니다.out.txt

편집하다

주석을 기반으로 다음 코드를 시도했습니다.

awk '{
    if (FNR==NR) {
        a[FNR]=$1;b[FNR]=$2;c[FNR]=$3}
    else {             
        if (a[FNR] == $1 && b[FNR] ==$2) {
            $6=c[FNR]} else {$6=$6};
           print $0;
        }
    }' file2 file1

이 출력을 얻으십시오

1201 12011 1 0 0 1 1
1202 12021 1 0 0 1 1
1203 12031 1 0 0 1 1
1204 12041 1 0 0 1 2
1207 12071 1 0 0 0 2
1209 12091 1 0 0 0 1
1210 12101 1 0 0 0 1
1212 12121 1 0 0 0 1
1213 12131 1 0 0 0 1
1214 12141 1 0 0 0 2

답변1

awk -F"\t" -v OFS="\t" '{
    if (FNR==NR) {
        a[FNR]=$1;b[FNR]=$2;c[FNR]=$3}
    else {
        if (a[FNR] == $1 && b[FNR] ==$2) {
            $6=c[FNR]} else {$6=$6};
            print $0
        }
    }' file2 file1

나는 이것이 일을 끝낼 것이라고 생각합니다. 먼저, 각각 인덱스를 사용하여 file2의 첫 번째, 두 번째 및 세 번째 열을 array 에 저장합니다 a( file2의 행에만 해당). Else (file1의 행에만 적용) 배열 sum의 값을 sum과 비교합니다. 일치하는 경우 배열의 6번째 필드를 변경합니다. 그렇지 않으면 값을 동일한 값에 다시 할당하고 구분 기호를 .bcFNRFNR = NRab$1$2ctab

답변2

큰 망치가 아닌 또 다른 awk접근 방식

while read f1 f2 f3; do 
    sed -E -i "s/^($f1\s+$f2.*)([0-9]+)$/\1$f3/" file1;
done < file2 

마지막 숫자가 정수라고 가정합니다. 그렇지 않은 경우 ([0-9])$적절한 캡처 그룹으로 수정해야 합니다.

이는 file1에 대한 내부 수정에 의존하므로 복사본이 필요합니다.

답변3

awk 스크립트를 보면 각 입력 파일을 다르게 처리하는 올바른 아이디어가 이미 있습니다(대부분의 경우 NR == FNR숫자 비교가 문자열 비교보다 빠르기 때문에 더 좋고 빠르게 작동하는지 확인하지만... ...수천 개의 입력이 있는 경우) 파일의 경우 이것이 중요합니다(하나 또는 두 개의 파일에 있는 입력 줄 수).

그러나 스크립트가 원하는 작업을 수행하지 못하게 하는 몇 가지 문제가 있습니다.

  1. 잘못된 순서로 파일을 읽고 있습니다. file1의 행을 출력하고 6열을 file2의 열 3으로 바꾸려고 하기 때문에 먼저 file2를 읽어 배열을 작성해야 합니다 m(file2의 인덱스 , file2의 $1,$2값 ). $3.

  2. 수정 m[$6]한 후 인쇄하고 있습니다. 최대 1개의 열이 인쇄됩니다.

다음과 같이 시도해 보세요.

$ awk 'NR == FNR    { m[$1,$2] = $3; next }
       ($1,$2) in m { $6 = m[$1,$2] }
       1' file2 file1
1201 12011 1 0 0 1 1
1202 12021 1 0 0 1 1
1203 12031 1 0 0 1 1
1204 12041 1 0 0 1 2
1207 12071 1 0 0 2 2
1209 12091 1 0 0 2 1
1210 12101 1 0 0 2 1
1212 12121 1 0 0 0 1
1213 12131 1 0 0 0 1
1214 12141 1 0 0 0 2

또는 NR == FNR첫 번째 줄을 원래 FILENAME == ARGV[1].

각 줄 file2(읽을 첫 번째 파일 - 명령줄의 파일 이름 인수 순서에 유의)에 대해 $3를 배열에 저장 m하고 다음 입력 줄로 점프합니다. 열 합계는 배열에 대한 인덱스 $1로 사용됩니다.$2

그런 다음 읽기 file1(및 후속 입력 파일이 있는 경우) 시 배열의 인덱스인 경우 배열에 저장된 값으로 ($1,$2)대체됩니다 .$6m

그런 다음 수정 여부에 관계없이 현재 입력 줄을 인쇄합니다(모드 자체는 1"현재 입력 줄 인쇄"를 의미하는 awk 관용구/단축 키입니다. "1"은 true로 평가되고 기본 작업은 "인쇄"입니다. . 그래서 사실상 "참이면 인쇄됩니다")

참고: 샘플 예상 출력을 제공하지 않았으므로 출력이 원하는 것과 일치하는지 확인할 수 없습니다. 일반적으로 OP의 샘플 출력을 파일에 저장하고 광산이 일치하는지 사용하거나 확인하는 것을 좋아 diff합니다 cmp. 내 awk 스크립트의 출력이 일치합니다.내 설명귀하의 질문에서 무엇을 요구하고 있습니까?

관련 정보