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

関連情報