HDFS 递归搜索grep

ws51t4hk  于 2022-12-09  发布在  HDFS
关注(0)|答案(4)|浏览(245)

我尝试在HDFS中搜索parquet文件并列出它们。我正在使用这个,它工作得很好。它搜索/sources.works_dbo中的所有子目录,并给我所有的parquet文件:

hdfs dfs -ls -R /sources/works_dbo | grep ".*\.parquet$"

然而,我只想返回每个子目录遇到的第一个文件,这样每个子目录在输出中只出现在一行中。假设我有这样的文件:

sources/works_dbo/test1/file1.parquet
sources/works_dbo/test1/file2.parquet
sources/works_dbo/test2/file3.parquet

当我运行命令时,我希望输出如下所示:

sources/works_dbo/test1/file1.parquet
sources/works_dbo/test2/file3.parquet
w41d8nur

w41d8nur1#

... | awk '!seen[gensub(/[^/]+$/,"",1)]++' file
sources/works_dbo/test1/file1.parquet
sources/works_dbo/test2/file3.parquet

上面的例子使用了GNU awk的gensub(),而其他awk则使用了一个变量和sub():

awk '{path=$0; sub(/[^/]+$/,"",path)} !seen[path]++'

它将适用于任何长度路径的任何混合。

f8rj6qna

f8rj6qna2#

您可以使用sort -u(unique),以/作为分隔符,并使用前三个字段作为关键字。-s选项(“stable”)确保保留的文件是每个子目录遇到的第一个文件。
对于此输入

sources/works_dbo/test1/file1.parquet
sources/works_dbo/test1/file2.parquet
sources/works_dbo/test2/file3.parquet

结果是

$ sort -s -t '/' -k 1,3 -u infile
sources/works_dbo/test1/file1.parquet
sources/works_dbo/test2/file3.parquet
t98cgbkg

t98cgbkg3#

如果子目录的长度是可变的,那么awk解决方案可能会派上用场:

hdfs dfs -ls -R /sources/works_dbo | awk '
     BEGIN{FS="/"; OFS="/";} 
     {file=$NF;                   // file name is always the last field
      $NF=""; folder=$0;          // chomp off the last field to cache folder
      if (!(folder in seen_dirs)) // cache the first file per folder
          seen_dirs[folder]=file;
     }
     END{
      for (f in seen_dirs)        // after we've processed all rows, print our cache
          print f,seen_dirs[f];
     }'
epfja78i

epfja78i4#

使用Perl:

hdfs dfs -ls -R /sources/works_dbo | grep '.*\.parquet$' | \
  perl -MFile::Basename -nle 'print unless $h{ dirname($_) }++'

在上面的 perl 命令中:

  • -M加载File::Basename模块;
  • -n使Perl将通过-e传递的表达式应用于每个输入行;
  • -l保留行终止符;
  • $_是保持当前读取行的默认变量;
  • dirname($_)返回由$_指定的路径的目录部分;
  • $h是散列,其中键是目录名,值是整数0、1、2等;
  • 除非在先前的迭代中看到目录名,即散列值$h{ dirname($_) }非零,否则该行被打印到标准输出。

顺便说一下,您可以使用find命令,而不是通过grephdfs dfs -ls -R的结果传送到管道:

hdfs dfs -find /sources/works_dbo -name '*.parquet'

相关问题