Bash 从上一行中减去

Bash 从上一行中减去,bash,awk,Bash,Awk,我试图从第2列中的当前分组行1中减去上一个分组行。例如,以下脚本重复了100次 A 322 0.2 322 0.2 322 0.2 B 455 0.35 455 0.35 455 0.35 C 566 0.92 566 0.92 566 0.92 A 322 0.18 322 0.18 322 0.18 B 455 0.33 455 0.33 455 0.33 C 566 0.99 566 0.99 566 0.99 我希望起点是A,这意味着第一组的分数0

我试图从第2列中的当前分组行1中减去上一个分组行。例如,以下脚本重复了100次

A   
322 0.2
322 0.2
322 0.2
B   
455 0.35
455 0.35
455 0.35
C   
566 0.92
566 0.92
566 0.92

A   
322 0.18
322 0.18
322 0.18
B   
455 0.33
455 0.33
455 0.33
C   
566 0.99
566 0.99
566 0.99
我希望起点是A,这意味着第一组的分数0.2将保持不变,第二组的分数0.18将保持不变。换句话说,先是C-B,然后是B-A。参见所需的输出

 A  
322 0.2
322 0.2
322 0.2
B   
455 0.15
455 0.15
455 0.15
C   
566 0.57
566 0.57
566 0.57

A   
322 0.18
322 0.18
322 0.18
B   
455 0.15
455 0.15
455 0.15
C   
566 0.66
566 0.66
566 0.66
我试图在第三列中打印这段代码,但它似乎是从前一行中减去的,而不是前一组

awk '{$3 = $2 - prev2; prev2 = $2; print;}'

awk
救援

根据公布的输入/输出和隐含假设

$ awk     '/^A/ {ia=1; c=0} 
             ia {a[c++]=$2} 
       /^[B-Z]/ {ia=c=0} 
    !ia && NF>1 {t=$2; $2-=a[++c]; a[c]=t}1' file

A
322 0.2
322 0.2
322 0.2
B
455 0.15
455 0.15
455 0.15
C
566 0.57
566 0.57
566 0.57

A
322 0.18
322 0.18
322 0.18
B
455 0.15
455 0.15
455 0.15
C
566 0.66
566 0.66
566 0.66
每个标题下的记录可以不同,但假定记录数相同

如果您的实际输入不由此示例表示,则可能需要调整条件

解释

/^A/{ia=1;c=0}
如果标签以
A
开头,则设置指示器
ai
,重置计数器

ia{a[c++]=$2}
如果在a中,则存储每个记录的值

/^[B-Z]/{ia=c=0}
对于其他标签,在A和计数器中重置

!ia&&NF>1{t=$2;$2-=a[++c];a[c]=t}
如果不在a和非标签中(字段数多于一个),则保存相应记录的数值、先前保存的偏移值,并将临时值保存为记录位置的新偏移值


1
print

awk
救命

根据公布的输入/输出和隐含假设

$ awk     '/^A/ {ia=1; c=0} 
             ia {a[c++]=$2} 
       /^[B-Z]/ {ia=c=0} 
    !ia && NF>1 {t=$2; $2-=a[++c]; a[c]=t}1' file

A
322 0.2
322 0.2
322 0.2
B
455 0.15
455 0.15
455 0.15
C
566 0.57
566 0.57
566 0.57

A
322 0.18
322 0.18
322 0.18
B
455 0.15
455 0.15
455 0.15
C
566 0.66
566 0.66
566 0.66
每个标题下的记录可以不同,但假定记录数相同

如果您的实际输入不由此示例表示,则可能需要调整条件

解释

/^A/{ia=1;c=0}
如果标签以
A
开头,则设置指示器
ai
,重置计数器

ia{a[c++]=$2}
如果在a中,则存储每个记录的值

/^[B-Z]/{ia=c=0}
对于其他标签,在A和计数器中重置

!ia&&NF>1{t=$2;$2-=a[++c];a[c]=t}
如果不在a和非标签中(字段数多于一个),则保存相应记录的数值、先前保存的偏移值,并将临时值保存为记录位置的新偏移值


1
print

我认为理想的操作是从B的第二列减去A的第二列(例如,
0.35-0.2=0.15/0.33-0.18=0.15
),从C的第二列减去B的第二列(例如,
0.92-0.35=0.57/0.99-0.33=0.66
),我添加了一些单词。我只想从B组中减去C组,然后从A组中减去B组。是的,有100次重复的重复块。您的输入有两个组,名为“A”,一个组的值都是0.2,另一个组的值都是0.18。他们有什么关系吗?我在您发布的输出中没有看到任何表示从B组减去C组的结果的内容。请检查您发布的输入/输出是否真实反映了您的真实问题以及您在文本中描述的内容。如果你有时有3行,有时有4行,在你的例子中,不要只是在评论中告诉我们。你没有任何答案并不意味着没有人可以回答,这意味着我们不知道你在问什么。那么,发布解决方案对任何人都没有用处。我认为理想的操作是从B的第二列减去A的第二列(例如,
0.35-0.2=0.15/0.33-0.18=0.15
),从C的第二列减去B的第二列(例如,
0.92-0.35=0.57/0.99-0.33=0.66
),我添加了一些单词。我只想从B组中减去C组,然后从A组中减去B组。是的,有100次重复的重复块。您的输入有两个组,名为“A”,一个组的值都是0.2,另一个组的值都是0.18。他们有什么关系吗?我在您发布的输出中没有看到任何表示从B组减去C组的结果的内容。请检查您发布的输入/输出是否真实反映了您的真实问题以及您在文本中描述的内容。如果你有时有3行,有时有4行,在你的例子中,不要只是在评论中告诉我们。你没有任何答案并不意味着没有人可以回答,这意味着我们不知道你在问什么。那么,发布解决方案对任何人都没有用处。只要把问题改进到可以理解的程度,或者把它删掉。这对我来说很有效。但什么是A、B、C……等等。以不同的名称更改,如A-22、A-30、C-55。我怎样才能解决它?提前感谢您解决了这个问题。而且,当我更改行数时,它们也会更改。例如,如果A组有5行,B组有2行。唯一常见的是每个组中的第一列。它要求组具有相同数量的元素,否则要减去什么?张贴具有代表性的样品很重要。代码执行您口头描述的操作。应该可以与任何其他标签一起使用,以
A开头的标签将按照您指定的方式重置流程。它对我很有效。但什么是A、B、C……等等。以不同的名称更改,如A-22、A-30、C-55。我怎样才能解决它?提前感谢您解决了这个问题。而且,当我更改行数时,它们也会更改。例如,如果A组有5行,B组有2行。唯一常见的是每个组中的第一列。它要求组具有相同数量的元素,否则要减去什么?张贴具有代表性的样品很重要。代码执行您口头描述的操作。应与任何其他标签一起使用,以
A开头的标签将按照您的指定重置流程。