grep 到多个文件,以便扫描一次输入文件



我有一百个CSV文件,每个文件有200k行,压缩成gzip。
具有相同结构的所有文件。第 15 列和第 18 列包含公司 ID 和操作。
两列在一行中都是唯一的。我想为每个 copanyID.action 创建一个文件。现在我运行以下命令:

zcat * | grep 'companyID.*action' | gzip > companyID.action.gz

我通过管道传输所有内容以避免磁盘 IO。

问题是我们有数百家公司和大约20项行动。在每个公司 ID X 操作上运行此命令,每次都会扫描整个数据。

我正在寻找一种解决方案,可以扫描一次输入文件并将一行写入正确的文件,如果该文件不存在,请创建一个。

我更喜欢 bash 或 Golang 代码,但速度很重要,所以每个解决方案都值得检查

awk 来做。

scat * | awk '{ print | "gzip > " $15 "." $18 ".gzip" }'

这应该可以做到:

zcat * |
awk -F, '{cmd="gzip >> ""$15"."$18".zip""} cmd!=prev{close(prev)} {print | cmd; prev=cmd}'

使用 GNU awk,您不需要cmd!=prev{close(prev)}部分,如果您这样做:

zcat * |
sort -t, -k15,15 -k18,18 |
awk -F, '{cmd="gzip > ""$15"."$18".zip""} cmd!=prev{close(prev)} {print | cmd; prev=cmd}'

它可能会运行得更快,因为它只会在 awk 命令中打开/关闭每个输出管道一次,只是取决于sort需要多长时间。

我不知道

scat是做什么的。我改用了zcat。我按相关列对所有文件的所有行进行排序,然后在 Perl 中处理输出,当相关列中的值更改时更改输出文件:

zcat *.csv.gz 
| sort -t, -k15,15 -k18,18 
| perl -laF, -ne '
    if ($company ne $F[14] || $action ne $F[17]) {
        ($company, $action) = @F[14, 17];
        open FH, ">", "$company.$action.csv"
    }
    print FH $_'
gzip *.*.csv

相关内容

  • 没有找到相关文章

最新更新