awk 명령에서 줄을 복사하는 방법은 무엇입니까? (ksh 스크립트 선호)

awk 명령에서 줄을 복사하는 방법은 무엇입니까? (ksh 스크립트 선호)

다음 색인 파일이 있습니다

 key1|1|1001
 key1|1|2001
 key2|2|3001
 key2|2|4001
 using this index file, I have to update my main file
 key1|1000|2000|3000|4000
 key2|1000|2000|3000|4000

 The expected output should be
 key1|1001|2000|3000|4000
 key1|2001|2000|3000|4000
 key2|1000|3001|3000|4000
 key2|1000|4001|3000|4000

그런데 아래의 script.awk는 메인 파일의 키를 복사하지 않고, 해당 인덱스의 값을 계속 덮어쓰고 있습니다. 스크립트에 어떤 문제가 있나요? awk -f script.awk index.txt main.txt

    #!/bin/awk
BEGIN {
    FS = "|"
}
( NR == FNR ) {
    lookup[toupper($1)] = $0
}

( NR > FNR ) {
    key = toupper($1)
    split(lookup[key], replacements, "|")
    for (i = 1; i <= NF; i++)
        col[i] = $i;
    for (i=1; i <= NF; i=i+1){
    j=replacements[i]
    col[j] = replacements[i+1]
    }
    for (i = 1; i <= NF; i++)
        printf "%s|", col[i]
}

답변1

당신은 꽤 가까워서 작업을 불필요하게 복잡하게 만들고 있습니다. 다음 스크립트를 사용해 보십시오 awk -f script.awk main.txt index.txt(파일의 역순에 주의하세요).

#!/bin/awk

BEGIN {
    FS = "|"
}
( NR == FNR ) {
    lookup[toupper($1)] = $0
}

( NR > FNR ) {
    key = toupper($1)
    n=split(lookup[key], replacements, "|")
    replacements[$2+1]=$3
    for (i=1; i<n+1; i++)
        printf "%s|", replacements[i]
    printf "\n"
}

밝혀지다

 key1|1001|2000|3000|4000|
 key1|2001|2000|3000|4000|
 key2|1000|3001|3000|4000|
 key2|1000|4001|3000|4000|

|파이프를 라인 끝에 유지하고 싶은지 확실하지 않지만 어쨌든 제거하는 것은 쉽지 않습니다.

접근 방식의 주요 문제점은 lookup새 행이 key이전 행과 동일한 값을 가질 때마다 배열을 덮어쓴다는 것입니다. 따라서 파일의 순서를 반대로 해야 합니다. 고유한 첫 번째 필드가 있는 파일을 먼저 읽어 배열 인덱스로 사용합니다.

그런데 이것은 순수한 솔루션이며 awk다른 쉘과는 아무런 관련이 없습니다.ksh

관련 정보