次のインデックスファイルがあります
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