我有一个带三个标头的csv。我想在其中添加一个额外的标头,称为“标签”。
$ cat TEST1/a.csv
h1,h2,h3
a,b,c
d,e,f
$ awk '{print $0}' TEST1/a.csv
h1,h2,h3
a,b,c
d,e,f
$ awk '{print $0, "tag"}' TEST1/a.csv
tag2,h3
tagc
tagf
但是,如上所示,当前方法正在提供垃圾值。我如何获得如下所示的输出:-
h1,h2,h3,tag
a,b,c,TEST1/a.csv
d,e,f,TEST1/a.csv
最好在标签列中包含文件名。
答案 0 :(得分:1)
我不确定您为什么会在第三个awk行中显示结果,我也不完全确定您要添加的最后一个字段是什么,因为您的“预期结果”不会与您提供的代码完全匹配。如果您的目标是在每行的最后一个字段中添加单词“ tag”,那么以下方法可能会起作用...
awk -F, '{$(NF+1)="tag"} 1' OFS=, TEST1/a.csv
这具有以下位:
-F,
将字段分隔符设置为逗号,与CSV兼容。$(NR+1)
在每个记录的末尾添加一个新字段。1
是“打印当前记录”的简写。OFS=,
将输出字段分隔符设置为逗号。有几种方法可以构造相同的逻辑,并且所有方法都可以提供大致相同的结果。
这将在BEGIN块中设置输入和输出字段分隔符,并使用字段的添加作为打印行的条件。
awk 'BEGIN{FS=OFS=","} $(NF+1)="tag"' TEST1/a.csv
省去了记录的概念,只在每一行中添加了文本。
awk '{$0=$0 ",tag"} 1' TEST1/a.csv
等
通常,如果您要处理字段中的输入,我建议使用awk来理解这些字段,以防万一您将来需要操纵字段而不是流。如果需要流编辑器,可以使用sed
。
sed 's/$/,tag/' TEST1/a.csv
另一方面, IF 您要在每行末尾添加文件名,并且仅在文本行中添加tag
标头,您可能会执行以下操作:
awk 'NR==1 {$(NF+1)="tag"} NR>1 {$(NF+1)=FILENAME} 1' FS=, OFS=, TEST1/a.csv
这将生成您显示的结果,文件名位于最后一个字段中。当然,您可以根据数据的形状进行各种变化。如果要处理多个文件,每个文件的第一行都有标题,则可能需要这样做:
awk 'NR==1 {$(NF+1)="tag";print} FNR==1 {next} NR>1 {$(NF+1)=FILENAME} 1' FS=, OFS=, file1.csv file2.csv ...
此处的区别在于,在第一行上修改了标头并进行了打印,然后完全跳过了后续的第一行文件。
答案 1 :(得分:1)
通过查看OP的输出,我相信OP所需的是第一行,它需要将tag
字符串添加到标题,其余各行应添加带有路径的文件名,如果是这种情况,请尝试以下。我还照顾了Input_file每行中的M \r
个字符。
awk 'BEGIN{OFS=","} {gsub(/\r/,"")} FNR==1{print $0,"tag";next} {print $0,FILENAME}' TEST1/a.csv
输出如下。
h1,h2,h3,tag
a,b,c,TEST1/a.csv
d,e,f,TEST1/a.csv
如果要先删除Input_file中的M个控制字符,然后运行awk
命令,然后使用以下命令。
tr -d '\r' '' < Input_file > temp_file && mv temp_file Input_file
然后按照awk
命令运行。
awk 'BEGIN{OFS=","}FNR==1{print $0,"tag";next} {print $0,FILENAME}' TEST1/a.csv