在当前行中使用上一行进行数学运算

mon*_*onk 3 bash awk

我有以下示例数据:

co1 co2 co3
100 200 300
110 230 310
125 235 320
Run Code Online (Sandbox Code Playgroud)

我需要对数据执行以下逻辑:

(col2 - col2 of the previous line)/(col1 - col1 of previous line) (col3-col3 of the previous line)/(col1 - col1 of previous line) 
Run Code Online (Sandbox Code Playgroud)

翻译成:

(230-200)/(110-100) (310-300)/(110-100)
(235-230)/(125-110) (320-310)/(125-110)
Run Code Online (Sandbox Code Playgroud)

我试过:

cat sample |awk 'NR>1' |'NR>1{f=$1;s=$2;t=$3;next} {print f,s;print $2-s/$1-f,$3-t/$1-f}'
Run Code Online (Sandbox Code Playgroud)

期望的输出:

3   1
0.3 0.6
Run Code Online (Sandbox Code Playgroud)

使用此逻辑输出将减少一行,因为第二行将消耗第一行。

以下数据出错:

 104937 20776001011 6893034089
 104937 20776001011 6893034089
 104938 20776062501 6893040119
 104938 20776062501 6893040119
 104938 20776062501 6893040119
 104938 20776062501 6893040119
 104938 20776062501 6893040119
 104939 20776124802 6893047227
 104939 20776124802 6893047227
 104939 20776124802 6893047227
 104939 20776124802 6893047227
 104940 20776178348 6893051452
 104940 20776178348 6893051452
 104940 20776178348 6893051452
 104940 20776178348 6893051452
 104940 20776178348 6893051452
 104941 20776235367 6893055075
 104941 20776235367 6893055075
 104941 20776235367 6893055075
 104941 20776235367 6893055075


61490 6030
awk: cmd. line:1: (FILENAME=- FNR=4) fatal: division by zero attempted
Run Code Online (Sandbox Code Playgroud)

Jam*_*own 5

另一种使用awk。每条记录都split指向一个数组a,该数组将在下一次迭代中使用:

$ awk 'NR>2{print ($2-a[2])/($1-a[1]),($3-a[3])/($1-a[1])} NR>1{split($0,a)}' file
3 1
0.333333 0.666667
Run Code Online (Sandbox Code Playgroud)

而不是仅仅printing 原始值,你可以printf用来格式化输出:从@RavinderSingh13 的回答中printf "%.01f %.01f\n", ... 被盗引用(并奖励:)...它会输出:

3.0 1.0
0.3 0.7
Run Code Online (Sandbox Code Playgroud)

%g %g 会输出:

3 1
0.333333 0.666667
Run Code Online (Sandbox Code Playgroud)

只需选择与您的首选输出类型差异最小的输出类型。


Ken*_*ent 5

另一个有趣的选择(使用粘贴和 awk):

paste file <(tail +2 file)|awk 'NF==6 && NR>1{a=$4-$1;b=$5-$2;c=$6-$3;
                                         printf "%.1f %.1f\n", b/a,c/a}'
Run Code Online (Sandbox Code Playgroud)