我想对hdfs中的一个目录中的单个文件(以及文件名)进行行计数,输出应该类似于:
4 filename_1.txt 20 filename_2.txt 8 filename_3.txt
目前我正在使用hadoop fs-cat/user/tmm/| wc-l它给出了目录的总计数(在这种情况下(例如:32)有什么办法吗?
j8ag8udp1#
您可以使用shell脚本来实现这一点,请参阅下面的代码片段。
for i in $( hadoop fs -ls <hdfs-path> | tr -s ' ' | grep '/' | awk '{print$8}'); do echo $i `hadoop fs -cat $i | wc -l`; done;
这将打印 hdfs-path 以及线路计数。[注:文件名打印在 hadoop fs -ls 我的hadoop版本的输出,请相应地在您的环境中检查]
hdfs-path
hadoop fs -ls
xurqigkl2#
如果您的数据量足够小,您可以这样做,但这种方法意味着将所有数据从hdfs客户机传输到客户机。不好的。另一种方法是创建mapreduce作业。从上下文中获取文件名(getinputsplit),并为每个输入行指定一个事件,其中键可以是文件名,值可以是1。最好在Map中创建一个局部聚合,以避免将大量对象传输到reducer。在reducer中完成聚合并将输出写入hdfs中的文件。
2条答案
按热度按时间j8ag8udp1#
您可以使用shell脚本来实现这一点,请参阅下面的代码片段。
这将打印
hdfs-path
以及线路计数。[注:文件名打印在
hadoop fs -ls
我的hadoop版本的输出,请相应地在您的环境中检查]xurqigkl2#
如果您的数据量足够小,您可以这样做,但这种方法意味着将所有数据从hdfs客户机传输到客户机。不好的。
另一种方法是创建mapreduce作业。从上下文中获取文件名(getinputsplit),并为每个输入行指定一个事件,其中键可以是文件名,值可以是1。最好在Map中创建一个局部聚合,以避免将大量对象传输到reducer。在reducer中完成聚合并将输出写入hdfs中的文件。