Awk 打印以两个字段为条件的连续行,并减去另一个字段

Awk 打印以两个字段为条件的连续行,并减去另一个字段,awk,field,line,matching,Awk,Field,Line,Matching,我想打印连续的行,如果他们有匹配的第一个领域,但相反的信号在第三个领域。然后计算连续行的第二个字段之间的距离 输入: id1 pos1 0.19 id1 pos2 0.33 id1 pos3 -0.25 id1 pos4 -0.22 id2 pos5 0.33 id3 pos6 -0.21 id3 pos7 -0.56 id3 pos8 -0.20 id3 pos9 0.33 id3 pos10 -0.32 中间输出: id1 pos2 0.33 id1 pos3 -0.25 id3 pos8

我想打印连续的行,如果他们有匹配的第一个领域,但相反的信号在第三个领域。然后计算连续行的第二个字段之间的距离

输入:

id1 pos1 0.19
id1 pos2 0.33
id1 pos3 -0.25
id1 pos4 -0.22
id2 pos5 0.33
id3 pos6 -0.21
id3 pos7 -0.56
id3 pos8 -0.20
id3 pos9 0.33
id3 pos10 -0.32
中间输出:

id1 pos2 0.33
id1 pos3 -0.25
id3 pos8 -0.20
id3 pos9 0.33
id3 pos10 -0.32
期望输出:

id1 pos3-pos2
id3 pos9-pos8
id3 pos10-pos9
我发现类似的问题比较连续的行,但没有一个可以用来回答我的问题

到目前为止,我试过:

awk '$1==prev1{$NF=$2-prev2;print $1,$NF} {prev2=$2;prev1=$1}'

但我不知道如何添加第三个字段的条件必须具有相反的信号。

根据您的描述,此
awk
应该:

awk '{sc=$3~/^-/?0:1} $1==p1&&sp!=sc {print $1,($3-p3)} {sp=sc;p1=$1;p3=$3}' file
id1 -0.58
id3 0.53
id3 -0.65
sc=$3~/^-/?0:1
测试值是否为正值
1
或负值
0

$1==p1&&sp=sc
如果当前ID等于以前的ID和值更改符号,
打印$1,($3-p3)
打印当前值和以前值之间的差值。

sp=sc;p1=1美元;p3=$3
将上一个设置为:sp设置为sc,p1设置为$1,p3设置为$3

请尝试以下设置

awk '
prev!=$1{
  prev_val=prev=""
}
prev==$1{
  if(($NF~/^-/ && prev_val!~/^-/) || ($NF!~/^-/ && prev_val~/^-/)){
     print $1,$2,$NF-prev_val
  }
}
{
  prev=$1
  prev_val=$NF
}
'  Input_file

这就是我问题的答案。感谢大家的帮助。

为什么这个输出
id3 pos8-0.20
而之前的值
id3 pos7-0.56
也是负值?通过相反的信号,是否从+到-?如果第一个字段与前一行相同(相同id),并且前一行中的第三个字段值为负,但当前行为正(或反之亦然),则从当前行减去前一行的字段2。(字段2是位置)我已更新了我的帖子。现在看一下在同一IDI中从+到-和从-到+的变化,我希望子动作字段2而不是字段4。@AEC,对不起,没有得到它,代码中没有提到字段4,
$NF
表示行的最后一个字段。对不起,我想说字段3而不是字段4。在你的情况下,我不想减去$NF,而是减去$2。但是我已经知道怎么做了,与上面的代码非常相似。@AEC,我不明白,您的示例显示的是
$3
(第三个字段),如果您的输入文件没有,您可以尝试更改一次,然后告诉我。您可以通过添加此选项编辑我的答案++也可以选择正确的答案。
awk  'prev1!=$1{
  prev3=prev2=prev1=""
}
prev1==$1{
  if(($3~/^-/ && prev3!~/^-/) || ($3!~/^-/ && prev3~/^-/)){
     print $1,$2-prev2
  }
}
{
  prev1=$1
  prev2=$2
  prev3=$3
}
'  Input