【问题标题】:How to add two columns based on header names and paste results in a third row based on header name?如何根据标题名称添加两列并根据标题名称将结果粘贴到第三行?
【发布时间】:2019-05-04 05:54:11
【问题描述】:

如何添加 2 列(测试 1 和测试 2)并根据列标题名称在第四列中打印结果? (CSV 文件)- 逗号分隔文件

输入:

test1 test2 test3 test4
1 2 x 
2 4 Y 

输出:

test1 test2 test3 test4
1 2 x 3
2 4 Y 6

我尝试了以下方法,但我希望它基于列标题而不是位置。

awk -F, '{$3=$1+$2;} {print $1,$2,$3}' OFS=, testing.csv

awk -F, '{$3=$1+$2;} {print $1,$2,$3}' OFS=, testing.csv

输入:

test1 test2 test3 test4
1 2 x 
2 4 Y 

输出:

test1 test2 test3 test4 
1 2 x 3
2 4 Y 6

【问题讨论】:

  • 如果您的输入和输出是逗号分隔的,那么在您的示例中显示 THAT,不要显示空格分隔而不是您的实际格式。
  • @EdMorton 很抱歉造成混乱。我现在已经提到它是一个 csv 文件 - 以逗号分隔。
  • 不要只提它——展示它。您的示例需要真正代表您的真实数据。如果您的真实数据以逗号分隔,则显示以逗号分隔的示例,而不是以空格分隔的示例。如果您的真实数据在数据行之间没有空行,则不要在示例中的数据行之间显示空行。
  • @EdMorton 使用“基于列标题”的方法——我们应该如何获取“列标题”的特定名称 i> 操纵?似乎我们将所有这些都归结为字段,而不管标题名称是什么,以便在最后一个字段中得出总和。除非您在某个时候将该信息传递到awk 脚本中,否则我看不到标题名称的相关性?我是否遗漏了一些明显的东西?
  • 好的,所以您的解释只是获取列标题字段名称并将它们用作数字引用来做同样的事情,但重要的是使用名称作为数字引用这里。如果这就是重点,那么是的,你做到了。我只是避免创建test1 = 1, test2 = 2, etc.. 的引用并使用数字本身。我采用这种方法是因为标题行名称与以后发生的任何其他事情之间完全没有任何关联。

标签: linux unix awk


【解决方案1】:

处理这个问题的最好方法是创建一个数组,在读取标题行时将列标题字符串(即字段名称)映射到字段编号,然后从那时起通过字段名称访问字段:

$ awk '
    NR==1 { for (i=1;i<=NF;i++) f[$i]=i }
    NR>1 { $(f["test4"]) = $(f["test1"]) + $(f["test2"]) }
1' file
test1 test2 test3 test4
1 2 x 3
2 4 Y 6

我在上面假设您的输入中的数据行之间实际上没有空行。如果你这样做了,处理起来很简单。

如果您的输入/输出确实是 CSV,那么只需创建一个 BEGIN 部​​分,声明:

$ cat file
test1,test2,test3,test4
1,2,x,
2,4,Y

$ awk 'BEGIN{FS=OFS=","} NR==1{for (i=1;i<=NF;i++) f[$i]=i} NR>1{$(f["test4"]) = $(f["test1"]) + $(f["test2"])} 1' file
test1,test2,test3,test4
1,2,x,3
2,4,Y,6

【讨论】:

  • 是的,它成功了!谢谢你。我对 unix 比较陌生,感谢您的帮助
  • 不客气。请仍然修复您问题中的示例,以使其对下一个寻求类似解决方案的人更有用。
【解决方案2】:

示例输入:

cat inputfile
test1 test2 test3 test4
1 2 x
2 4 Y

在这里,从第一行读取标题并获取 test1 和 test2 的列号并将其存储到变量 t1t2 中,然后将 $4 与其自身和 t1 指向的列之和重新分配和t2

awk 'NR==1{for(i=1;i<=NF;i++) if($i=="test1") t1=i; else if($i=="test2") t2=i} NR>1{$4=$4 FS $t1+$t2} {print }' inputfile
test1 test2 test3 test4
1 2 x  3
2 4 Y  6

如果您的输入文件中有空行并且想要保留它们,请使用NF 作为非零检查,如NR&gt;1&amp;&amp; NF{$4=$4 FS $t1+$t2}

【讨论】:

  • 嗨@EdMorton 我想打印所有列,但目前只打印一列。此外,是否可以将列标题设置为 $4 而不是 $4
猜你喜欢
  • 1970-01-01
  • 2022-11-28
  • 2019-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-07
  • 1970-01-01
相关资源
最近更新 更多