首页 > 解决方案 > 如何将文件的行号添加到 Hive 表中

问题描述

有没有办法使用文件的行号将多个文件加载到 Hive 表中?我可以很好地加载文件中的每个条目,并且我知道您可以使用 input__file__name 来获取代码来自的文件的名称,那么是否有类似的方法来提取代码来自文件的哪一行?

给定这三个任意文件:

a.txt           b.txt          c.txt
a1              b1             a3
b2              b2             b3
c3              c3             c4

有没有办法将它们加载到 Hive 表中,其中包含它来自的文件的行号?注意:实际文件没有附加编号。结果,我想要这个结果:

SELECT * FROM result;

将产生:

Line_Number             code
1                       a1
1                       b1
1                       c1
2                       a2
2                       b2
2                       c2
3                       a3
3                       b3
3                       c3

标签: hivehiveql

解决方案


仅使用 HiveQL 是不可能的,因为文件是可拆分的并且可以被许多映射器读取。分裂不是线。文件按字节拆分,而不是行边界。并且拆分由映射器独立处理。映射器对彼此一无所知。简单的方法是预处理您的文件并使用 shell/etc 添加行号,然后将它们加载到定义了 line_number 列的表中。例如,使用awk

 awk '{printf "%s\t%s\n",NR,$0}' a.txt > a1.txt

这将添加一个带有行号的列,制表符分隔。a.txt- 是输入文件,a1.txt- 结果文件

如果您想为此目的使用 Map-reduce,您需要实现自己的TextInputFormat/LineRecordReader以返回行号作为键而不是字节偏移量。此外,它不应该拆分文件以生成序列号,这会破坏并行性。也许可以使用自定义计数器在映射器之间同步数字生成来做到这一点。无论如何,以完全分布式的方式做到这一点并不是一件容易的事。所以,我建议在加载到表格之前预处理文件并添加行号。


推荐阅读