AWK:模式匹配具有可变行号的多行数据
AWK: Pattern match multiline data with variable line number
我正在尝试编写一个脚本来分析来自管道的数据。问题是,单个元素的描述行数可变。查看示例数据集:
3 14 -30.48 17.23
4 1 -18.01 12.69
4 3 -11.01 2.69
8 12 -21.14 -8.76
8 14 -18.01 -5.69
8 12 -35.14 -1.76
9 2 -1.01 22.69
10 1 -88.88 17.28
10 1 -.88 14.28
10 1 5.88 1.28
10 1 -8.88 -7.28
在这种情况下,第一个条目定义了以下数据所属的事件。对于事件编号 8,我们有 3 行数据。为了简化我试图解决的相当复杂的问题,让我们想象一下,我想计算以下表达式:
sum_i( * ( + ))
其中 i 接管属于给定元素的所有行。我想要生成的输出将如下所示:
3=-185.5 [14(-30.48+17.23) ]
4=-30.28 [1(-18.01+12.69) + 3(-11.01+2.69)]
8=-1106.4 [...]
因此我需要一个脚本来读取具有相同索引条目的所有行。
我是 AWK 新手,几天前我开始学习这门语言。我现在不确定我是否能够实现我想要的。因此:
- 这对 AWK 可行吗?
- 如果不是,那是什么? SED?
- 如果是,怎么样?如果有人提供 link 描述如何实现这一点,我将不胜感激。
最后,我知道有一个类似的问题:Can awk patterns match multiple lines?,但是,我没有一个常量模式来分隔我的数据。
谢谢!
awk 'id!={if(id){print id"="sum;sum=0};id=}{sum+=*(+)} END{print id"="sum}' file
3=-185.5
4=-30.28
8=-1133.4
9=43.36
10=-67.2
你可以试试这个:
awk '{ar[]+=*(+)}
END{for (key in ar)
{print key"="ar[key]}}' inputFile
对于每一行输入,我们都会进行所需的计算并将结果求和到一个数组中。 </code>作为数组的键。<br>
读取整个文件后,我们在 <code>END{...}
块中打印结果。
给定样本输入的输出是:
4=-30.28
8=-1133.4
9=43.36
10=-67.2
3=-185.5
如果需要对输出进行排序,您可能需要查看 gawk 的 asorti
函数或 Linux' sort
-命令(例如 awk '{...} inputFile' | sort -n
) .
此解决方案不需要对输入进行排序。
又一个类似的 awk
$ awk -v OFS="=" 'NR==1{p=}
p!={print p,s; s=0; p=}
{s+=*(+)}
END{print p,s}' file
3=-185.5
4=-30.28
8=-1133.4
9=43.36
10=-67.2
ps。您对“8”的计算似乎有误。
我正在尝试编写一个脚本来分析来自管道的数据。问题是,单个元素的描述行数可变。查看示例数据集:
3 14 -30.48 17.23
4 1 -18.01 12.69
4 3 -11.01 2.69
8 12 -21.14 -8.76
8 14 -18.01 -5.69
8 12 -35.14 -1.76
9 2 -1.01 22.69
10 1 -88.88 17.28
10 1 -.88 14.28
10 1 5.88 1.28
10 1 -8.88 -7.28
在这种情况下,第一个条目定义了以下数据所属的事件。对于事件编号 8,我们有 3 行数据。为了简化我试图解决的相当复杂的问题,让我们想象一下,我想计算以下表达式:
sum_i( * ( + ))
其中 i 接管属于给定元素的所有行。我想要生成的输出将如下所示:
3=-185.5 [14(-30.48+17.23) ]
4=-30.28 [1(-18.01+12.69) + 3(-11.01+2.69)]
8=-1106.4 [...]
因此我需要一个脚本来读取具有相同索引条目的所有行。
我是 AWK 新手,几天前我开始学习这门语言。我现在不确定我是否能够实现我想要的。因此:
- 这对 AWK 可行吗?
- 如果不是,那是什么? SED?
- 如果是,怎么样?如果有人提供 link 描述如何实现这一点,我将不胜感激。
最后,我知道有一个类似的问题:Can awk patterns match multiple lines?,但是,我没有一个常量模式来分隔我的数据。
谢谢!
awk 'id!={if(id){print id"="sum;sum=0};id=}{sum+=*(+)} END{print id"="sum}' file
3=-185.5
4=-30.28
8=-1133.4
9=43.36
10=-67.2
你可以试试这个:
awk '{ar[]+=*(+)}
END{for (key in ar)
{print key"="ar[key]}}' inputFile
对于每一行输入,我们都会进行所需的计算并将结果求和到一个数组中。 </code>作为数组的键。<br>
读取整个文件后,我们在 <code>END{...}
块中打印结果。
给定样本输入的输出是:
4=-30.28
8=-1133.4
9=43.36
10=-67.2
3=-185.5
如果需要对输出进行排序,您可能需要查看 gawk 的 asorti
函数或 Linux' sort
-命令(例如 awk '{...} inputFile' | sort -n
) .
此解决方案不需要对输入进行排序。
又一个类似的 awk
$ awk -v OFS="=" 'NR==1{p=}
p!={print p,s; s=0; p=}
{s+=*(+)}
END{print p,s}' file
3=-185.5
4=-30.28
8=-1133.4
9=43.36
10=-67.2
ps。您对“8”的计算似乎有误。