这么多的(轻微)的变化同一主题。
awk '
!($1 in a) {a[$1]=$2; next}
{a[$1]-=$2}
END {for (i in a) printf "%s %d\n",i,a[i]}
' input.txt
如果您愿意,可将其叠加为一行。
请记住,awk结构由多个condition { statement }
对组成,因此您可以比使用if..else
更优雅地表达您的需求。 (并不是说这里就是这种情况 - 这是一个足够简单的awk脚本,它可能并不重要,除非你是一个纯粹主义者。])
另外,要小心测试值的方式,已经在你的if
的条件下完成了这个问题。请注意,a[$1]
都测试该数组索引处的值是否为非零值和如果先前不存在,则会使索引存在空值。如果您想检查索引是否存在,请使用$1 in a
。
更新基于对您的问题评论...
如果你想减去从第一项最后,忽略之间的,那么你需要保持记录你的第一个和你的最后一个。像这样的东西可能就足够了。
awk '
!($1 in a){a[$1]=$2;next}
{b[$1]=$2}
END {for(i in b)if(i in a)print i,a[i]-b[i]}
' input.txt
请注意,正如埃德提到的,这会产生随机顺序的输出。如果你想要输出的顺序,你需要一个额外的数组来跟踪订单。例如,这将使用顺序的项目,首先看出:
awk '
!($1 in a) {
a[$1]=$2;
o[++n]=$1;
next
}
{
b[$1]=$2
}
END {
for (n=1;n<=length(o);n++)
print o[n],a[o[n]]-b[o[n]]
}
' i
注意,所使用的length()
函数来确定数组中元素的数目是不普遍之中AWK的方言,但它确实在两个工作gawk和one-true-awk(用于FreeBSD等)。
如果第一列中的值重复多次,会发生什么? – ghoti
在这种情况下,我想采取第一次和最后一次发生 – Vicky
发布的解决方案都不会这样做,他们所做的只是为您提供的2入口示例(除了我的所有内容之外,不必要地将数据的一半保存在数组中然后以随机顺序产生输出,而不是严格按照键值读取的顺序进行输出,这可能或可能不合意)。 –