替换csv

时间:2016-02-09 09:23:39

标签: regex bash csv awk sed

我有一个像这样的csv文件

 KEY,F1,F2,STEP,LAST_OCCURRENCE
 100.101,a,b,STEP_1,<empty>
 100.102,c,d,STEP_1,<empty>
 100.103,e,f,STEP_1,<empty>
 100.101,g,h,STEP_1,<empty>
 100.103,i,j,STEP_1,<empty>
 100.101,g,h,STEP_2,<empty>
 100.103,i,j,STEP_2,<empty>

我能够将最终字段更改为最容易解析的字段,因此可以将其视为空白,,\n或包含上述<empty>一词。

从这个文件我必须更换&#34; LAST_OCCURRENCE&#34;字段与最后一次出现的[KEY + STEP]值匹配,带有一个布尔值(表示它是元组的最后一个值)。

预期结果是这一个:

 KEY,F1,F2,STEP,LAST_OCCURRENCE
 100.101,a,b,STEP_1,false
 100.102,c,d,STEP_1,true     #Last 100.102 for STEP_1
 100.103,e,f,STEP_1,false
 100.101,g,h,STEP_1,true     #Last 100.101 for STEP_1
 100.103,i,j,STEP_1,true     #Last 100.103 for STEP_1
 100.101,g,h,STEP_2,true     #Last 100.101 for STEP_2
 100.103,i,j,STEP_2,true     #Last 100.103 for STEP_2

哪种方法最快? 可以使用sed脚本来完成它,或者更好地用另一个(perl?php?)脚本对输入文件进行后处理?

2 个答案:

答案 0 :(得分:2)

使用tacawk

tac file |
awk 'BEGIN{FS=OFS=","} $1 != "KEY"{$NF = (seen[$1,$4]++) ? "false" : "true"} 1' |
tac

使用tac以相反的顺序列出文件后,我们使用一个关联数组seen,其复合键为$1,$4,以确定每个复合键的第一次出现。最后,我们执行tac以按原始顺序恢复文件。

输出

KEY,F1,F2,STEP,LAST_OCCURRENCE
100.101,a,b,STEP_1,false
100.102,c,d,STEP_1,true
100.103,e,f,STEP_1,false
100.101,g,h,STEP_1,true
100.103,i,j,STEP_1,true
100.101,g,h,STEP_2,true
100.103,i,j,STEP_2,true

答案 1 :(得分:1)

 $ awk 'BEGIN{FS=OFS=","} NR==FNR{last[$1,$4]=NR;next} FNR>1{$NF=(FNR==last[$1,$4] ? "true" : "false")} 1' file file
 KEY,F1,F2,STEP,LAST_OCCURRENCE
 100.101,a,b,STEP_1,false
 100.102,c,d,STEP_1,true
 100.103,e,f,STEP_1,false
 100.101,g,h,STEP_1,true
 100.103,i,j,STEP_1,true
 100.101,g,h,STEP_2,true
 100.103,i,j,STEP_2,true