更新文本文件的一列,并用变量名写入输出



我有一个带有ID和价格的项目记录,并尝试根据另一个"引用文件"更新其中一些项目的价格,该文件的格式为item# NewPrice OutFile。最终,我们将拥有与ref文件中的#行一样多的输出记录(这里有4个输出)。OutFiles将与原始文件相似,除了调整的项目。下面是我的文件和不能工作的awk脚本。谢谢你的帮助。

Main file  [Item # current_value]:
Item  1  20 
Item  2  30
Item  3  40
Reference file  [Item# new_value outputfile]
1  22  It1_22
1  25  It1_25
2  32  It2_32
3  45  It3_45
Expected Output files:
(It1_22)
Item,1,22
Item,2,30
Item,3,40
(It1_25)
Item,1,25
Item,2,30
Item,3,40
(It2_32)
Item,1,20
Item,2,32
Item,3,40
(It3_45)
Item,1,20
Item,2,30
Item,3,45

我的脚本没有生成任何文件:

awk 'BEGIN{OFS=","};FNR == NR{a[$1]=$2;d=$3;next} $2 in a{print $1,$2,a[$2];next}1' ref  main > d

为数组的数组和无限打开的文件使用GNU awk:

$ cat tst.awk
BEGIN { OFS = "," }
NR == FNR {
vals[$3][$1] = $2
next
}
{
for ( fname in vals ) {
print $1, $2, ($2 in vals[fname] ? vals[fname][$2] : $3) > fname
}
}

$ awk -f tst.awk ref main

$ head It*
==> It1_22 <==
Item,1,22
Item,2,30
Item,3,40
==> It1_25 <==
Item,1,25
Item,2,30
Item,3,40
==> It2_32 <==
Item,1,20
Item,2,32
Item,3,40
==> It3_45 <==
Item,1,20
Item,2,30
Item,3,45

你可以使用任何awk做同样的事情,它只是运行得慢一点,因为它必须为每次写入打开/关闭每个输出文件,而不是gawk,它只在必要时才这样做,以避免"打开的文件太多"。错误:

$ cat tst.awk
BEGIN { OFS = "," }
NR == FNR {
vals[$3,$1] = $2
fnames[$3]
printf "" > $3
close($3)
next
}
{
for ( fname in fnames ) {
print $1, $2, ((fname,$2) in vals ? vals[fname,$2] : $3) >> fname
close(fname)
}
}

这里有一个解决方案,没有任何错误处理的缺失值等。要保持数据文件的顺序,请将每个与行号相关联,并在打印时恢复。

$ awk -v OFS=, 'NR==FNR{k=$2; n[k]=$1; v[k]=$3; ord[NR]=k; next}                        
{for(i=1;i<=length(ord);i++) 
{k=ord[i]; 
print n[k],k,k==$1?$2:v[k] > $3}}' mainfile reffile 

$ head It*
==> It1_22 <==
Item,1,22
Item,2,30
Item,3,40
==> It1_25 <==
Item,1,25
Item,2,30                                                                                                      
Item,3,40                                                                                                      
                                         
==> It2_32 <==                                                                                                 
Item,1,20                                                                                                      
Item,2,32                                                                                                      
Item,3,40                                                                                                      
                                         
==> It3_45 <==                                                                                                 
Item,1,20                                                                                                      
Item,2,30                                                                                                      
Item,3,45