我有一个制表符分隔的数据集,例如:
#1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1 10024 10395 41 K + 2 1 1 12 14 5 0 0 3 1 3 6 2
1 10679 10795 51 P + 2 1 1 15 14 3 0 0 2 1 2 3 1
我想再添加一列($20)来存储基于第 7-19 列的值:如果列中的数字不等于 0,则加一。预期输出:
#1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 10024 10395 41 K + 2 1 1 12 14 5 0 0 3 1 3 6 2 11
1 10679 10795 51 P + 2 1 1 15 14 3 0 0 2 1 2 3 1 11
如何使用awk编写命令?
答案1
可以从第7个字段开始迭代,检查该字段的值是否为0;如果不是,则将第 20 个字段继续加 1:
awk -F '\t' 'NR==1 {$(NF+1)=NF+1; print; next}; \
{for(i=7; i<NF; i++) if ($i != 0) $20++}; 1' OFS='\t' file.txt
对于第一条记录 ( NR==1
),添加了一个额外的字段标头作为最后一个字段,并向当前 . 添加 1 NF
。
答案2
perl -aF'\t' -lpe '$_ .= "\t" . ($. == 1 ? @F+1 : grep $_, @F[6..$#F])' data.set
由于我们需要在行尾添加另一个字段,因此我们.=
在当前记录上使用运算符$_
。对于第一个记录的特殊情况,我们只需附加表达式@F+1
,该表达式在标量上下文中解释为当前字段数加 1。
对于非标头记录,表达式grep $_, @F[6..$#F]
意味着迭代第 7 个元素到数组的最后一个元素@F
(这是使用选项卡字段分隔符从记录中切出的,通过选项指定-F'\t'
。在标量上下文中,它返回乘以条件(在我们的例子中),$_
表示切片中第 7 个...直到最后一个元素中的非零元素。
结果
#1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 10024 10395 41 K + 2 1 1 12 14 5 0 0 3 1 3 6 2 11
1 10679 10795 51 P + 2 1 1 15 14 3 0 0 2 1 2 3 1 11