20

我正在使用 Hadoop,我需要在我的 Hadoop 文件系统中找到大约 100 个文件中的哪些文件包含某个字符串。

我可以像这样看到我想搜索的文件:

bash-3.00$ hadoop fs -ls /apps/mdhi-technology/b_dps/real-time

..它返回几个这样的条目:

-rw-r--r--   3 b_dps mdhi-technology 1073741824 2012-07-18 22:50 /apps/mdhi-technology/b_dps/HADOOP_consolidated_RT_v1x0_20120716_aa
-rw-r--r--   3 b_dps mdhi-technology 1073741824 2012-07-18 22:50 /apps/mdhi-technology/b_dps/HADOOP_consolidated_RT_v1x0_20120716_ab

如何找到其中哪些包含字符串bcd4bc3e1380a56108f486a4fffbc8dc?一旦我知道,我可以手动编辑它们。

4

5 回答 5

36

这是一个 hadoop “文件系统”,而不是 POSIX 系统,所以试试这个:

hadoop fs -ls /apps/hdmi-technology/b_dps/real-time | awk '{print $8}' | \
while read f
do
  hadoop fs -cat $f | grep -q bcd4bc3e1380a56108f486a4fffbc8dc && echo $f
done

这应该可行,但它是串行的,因此可能很慢。如果您的集群可以承受热量,我们可以并行化:

hadoop fs -ls /apps/hdmi-technology/b_dps/real-time | awk '{print $8}' | \
  xargs -n 1 -I ^ -P 10 bash -c \
  "hadoop fs -cat ^ | grep -q bcd4bc3e1380a56108f486a4fffbc8dc && echo ^"

注意-P 10选项xargs:这是我们将并行下载和搜索的文件数量。从低处开始并增加数量,直到磁盘 I/O 或网络带宽饱和,无论您的配置是否相关。

编辑:鉴于您使用的是 SunOS(有点脑残),请尝试以下操作:

hadoop fs -ls /apps/hdmi-technology/b_dps/real-time | awk '{print $8}' | while read f; do hadoop fs -cat $f | grep bcd4bc3e1380a56108f486a4fffbc8dc >/dev/null && echo $f; done
于 2012-07-28T02:44:02.127 回答
0

如果您只有两个 1 GB 文件,则使用hadoop fs -cat(或更通用的)可能是可行的。hadoop fs -text对于 100 个文件,尽管我会使用流式 API,因为它可以用于临时查询,而无需借助完整的 mapreduce 作业。例如,在您的情况下创建一个脚本get_filename_for_pattern.sh

#!/bin/bash
grep -q $1 && echo $mapreduce_map_input_file
cat >/dev/null # ignore the rest

请注意,您必须阅读整个输入,以避免出现java.io.IOException: Stream closed异常。

然后发出命令

hadoop jar $HADOOP_HOME/hadoop-streaming.jar\
 -Dstream.non.zero.exit.is.failure=false\
 -files get_filename_for_pattern.sh\
 -numReduceTasks 1\
 -mapper "get_filename_for_pattern.sh bcd4bc3e1380a56108f486a4fffbc8dc"\
 -reducer "uniq"\
 -input /apps/hdmi-technology/b_dps/real-time/*\
 -output /tmp/files_matching_bcd4bc3e1380a56108f486a4fffbc8dc
hadoop fs -cat /tmp/files_matching_bcd4bc3e1380a56108f486a4fffbc8dc/*

在较新的发行版mapred streaming中,而不是hadoop jar $HADOOP_HOME/hadoop-streaming.jar应该工作。在后一种情况下,您必须$HADOOP_HOME正确设置才能找到 jar(或直接提供完整路径)。

对于更简单的查询,您甚至不需要脚本,只需将命令-mapper直接提供给参数即可。但是对于任何稍微复杂的事情,最好使用脚本,因为获得转义权可能是一件苦差事。

如果您不需要减少阶段NONE,请为相应的-reduce选项提供符号参数(或仅使用-numReduceTasks 0)。但是在您的情况下,为了将输出合并到一个文件中,有一个减少阶段很有用。

于 2017-05-09T01:03:40.757 回答
0

您正在寻找对 hdfs 文件夹应用 grep 命令

hdfs dfs -cat /user/coupons/input/201807160000/* | grep -c null

这里 cat 递归遍历文件夹中的所有文件,我已应用 grep 来查找计数。

于 2018-08-24T05:20:42.780 回答
0

要在 hdfs 位置递归查找具有任何扩展名的所有文件:

hadoop fs -find  hdfs_loc_path  -name ".log"
于 2019-06-24T14:01:44.130 回答
0
hadoop fs -find /apps/mdhi-technology/b_dps/real-time  -name "*bcd4bc3e1380a56108f486a4fffbc8dc*"

hadoop fs -find /apps/mdhi-technology/b_dps/real-time  -name "bcd4bc3e1380a56108f486a4fffbc8dc"
于 2019-07-26T21:18:00.027 回答