regex - 用于合并具有匹配的第一个字段的行的命令行,50 GB 输入

标签 regex optimization awk sed

不久前,我问了一个关于合并具有共同第一个字段的行的问题。原文如下:Command line to match lines with matching first field (sed, awk, etc.)

示例输入:

a|lorem
b|ipsum
b|dolor
c|sit
d|amet
d|consectetur
e|adipisicing
e|elit

期望的输出:

b|ipsum|dolor
d|amet|consectetur
e|adipisicing|elit

这个想法是,如果第一个字段匹配,则合并行。输入已排序。实际内容更复杂,但使用管道作为唯一的分隔符。

上一个问题中提供的方法在我的 0.5GB 文件上运行良好,处理时间约为 16 秒。但是,我的新文件大约大 100 倍,而且我更喜欢流式传输的方法。理论上,这将能够在大约 30 分钟内运行。之前的方法运行24小时后未能完成。

在 MacOS(即 BSD 类型的 unix)上运行。

想法? [注意,之前问题的先前回答不是一句空话。]

最佳答案

您可以将结果附加到动态文件中,这样您就不需要构建 50GB 的数组(我假设您没有足够的内存!)。此命令将连接字符串中每个不同索引的连接字段,该字符串将写入到以相应索引命名的文件中,并带有一些后缀。

编辑:根据OP评论内容可能有空格,我建议使用-F"|"而不是sub并且以下答案旨在写入标准输出

(新)代码:

# split the file on the pipe using -F
# if index "i" is still $1 (and i exists) concatenate the string
# if index "i" is not $1 or doesn't exist yet, print current a
# (will be a single blank line for first line)
# afterwards, this will print the concatenated data for the last index
# reset a for the new index and take the first data set
# set i to $1 each time
# END statement to print the single last string "a"
awk -F"|" '$1==i{a=a"|"$2}$1!=i{print a; a=$2}{i=$1}END{print a}' 

这会在给定索引中构建一串“数据”,然后在索引更改时将其打印出来,并开始在新索引上构建下一个字符串,直到该字符串结束...重复...

关于regex - 用于合并具有匹配的第一个字段的行的命令行,50 GB 输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31729187/

相关文章:

javascript - 对 `RexExp.prototype.exec`的返回值类型感到困惑

java - java 是否优化字符串文字 toLowerCase()?

bash - gawk 用于使用变量将包含模式的行替换为多行

algorithm - 最大多样性 : translate an heuristic algorithm in C (or pseudocode)

shell - ipython shell awk : Escaping "$" sign

linux - 列中的最小值、平均值和最大值

c# - 这个正则表达式是什么意思

用于从 URL/网站获取带有子域的域的 PostgreSQL 正则表达式

javascript - 正则表达式允许十进制数大于 0 且小于 100

Python列表比较numpy优化