awk 如何与 HDFS 目录一起工作?

How does awk work with directory of HDFS?

我想把HDFS的目录名和awk结合起来。这可行吗?目录名,不是文件名。 这是我在本地的 awk 工作正常:

awk 'NR <= 1000 && FNR == 1{print FILENAME}' ./* 

然后我想将它与 hadoop fs -ls 结合起来,如下所示:

hadoop fs -ls xxx/* | xargs awk 'NR <= 1000 && FNR == 1{print FILENAME}'

但告诉我:awk:cmd。 line:2:致命:无法打开文件“-rwxrwxrwx”进行读取(没有这样的文件或目录)

我也试过:

awk 'NR <= 1000 && FNR == 1{print FILENAME}' < hadoop fs -ls xxx/*
awk 'NR <= 1000 && FNR == 1{print FILENAME}' < $(hadoop fs -ls xxx/*)
awk 'NR <= 1000 && FNR == 1{print FILENAME}' $(hadoop fs -ls xxx/*)

这些都毫无意外地失败了,我认为awk执行目录中的文件需要读取每个文件,而不是像可以将其作为流传递给awk的文件内容。我对吗?谁能给我一个可行的解决方案来做到这一点?谢谢,提前。

在我看来,您想访问 hadoop 文件系统上的文件。这是一个虚拟文件系统,您只能访问文件的元数据。如果你想对你的文件进行操作,那么首先将文件复制到本地也很重要。这可以使用 hadoop fs -get 来完成。创建本地副本后,您可以开始对文件进行操作。然而,还有另一种方法使用 hadoop fs -cat.

通常我会说 Never parse the output of ls,但是对于 Hadoop,您别无选择。 hadoop fs -ls 的输出与 Unix/Linux 命令 ls 的标准输出不同。它与以下输出 ls -l 和 returns 密切相关:

permissions number_of_replicas userid groupid filesize modification_date modification_time filename

使用它并将其通过管道传输到 awk 我们得到一个可用文件列表。所以我们现在可以设置一个 while 循环:

c=0
while read -r file; do
   [ $c -le 1000 ] && echo "${file}"
   nr=$(hadoop fs -cat "${file}" | wc -l)
   ((c+=nr))
done < <(hadoop fs -ls xxx/* | awk '!/^d/{print substr([=11=],index(,[=11=]))}')

注意: 您最初的错误是由于 hadoop fs -ls 的非类 unix 输出造成的。程序 awk 收到一个文件名 -rwxrwxrwx 这实际上是文件本身的权限。