我的数据文件如下所示:
10 -0.314690785295
20 -0.251967909317
30 -0.215271387106
40 -0.189228416217
期望的输出是:
10 -0.0627229
20 -0.0994193
30 -0.1254623
答案1
awk 'BEGIN {first_row = 0; col_val=""}{ if (first_row == 0) {first_row = $2; col_val=$1} else {print col_val " " first_row - $2; col_val=$1}}'
这是命令行的输出:
$ echo "10 -0.314690785295
20 -0.251967909317
30 -0.215271387106
40 -0.189228416217" | awk 'BEGIN {first_row = 0; col_val=""}{ if (first_row == 0) {first_row = $2; col_val=$1} else {print col_val " " first_row - $2; col_val=$1}}'
10 -0.0627229
20 -0.0994194
30 -0.125462
好的,现在解释一下为什么会这样:
BEGIN 子句定义了在开始之前作为初始化执行的一段代码。在此位置,我们初始化两个变量,我们将在其余逻辑中跟踪这两个变量。
在程序的主要部分,在第二组{}中。我们定义将为输入中的每一行执行的逻辑(您也可以在前面添加一个模式以仅在某些行上运行,但这超出了本答案的范围)。
该逻辑测试是否设置了first_row 值。如果不是,那么这是输入的第一行,我们只需将first_row值初始化为该行中的第二个字符串$2,我们还需要复制第一列$1中的字符串为了匹配您所需的输出,我们将该值复制到 col_val 中。
否则,即输入中的每隔一行,我们打印 col_value 一个空格,以及将first_row 与当前行第二个位置 $2 的值相减的结果,因此first_row - $2。然后,我们将输入第一列中的新字符串值复制到 col_val 中。
我第一次不明白你真正需要什么:)..这是一个 awk 脚本,它会做你想做的事..因为 10 - 20 是 -10 而不是 10。
awk '{ if (NR == 1) { for (i = 1; i <= NF; i++){ first_row[i] = $i} } else { for (i = 1; i <= NF; i++){ printf "%s ", first_row[i] - $i }; printf "\n"}}'
请注意,输出看起来像这样,与您对第一列的预期略有不同,我添加了另一列来显示进度。
echo "10 -0.314690785295 18
20 -0.251967909317 12
30 -0.215271387106 35
40 -0.189228416217 44" | awk '{ if (NR == 1) { for (i = 1; i <= NF; i++){first_row[i] = $i} } else { for (i = 1; i <= NF; i++){ printf "%s ", first_row[i] - $i }; printf "\n"}}'
-10 -0.0627229 6
-20 -0.0994194 -17
-30 -0.125462 -26