递归搜索grep

时间:2017-01-24 00:38:32

标签: linux grep hdfs

我正在尝试在HDFS中搜索镶木地板文件并将其列出。我正在使用它,效果很好。它查看了/sources.works_dbo中的所有子目录,并为我提供了所有镶木地板文件:

 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

4 个答案:

答案 0 :(得分:2)

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

以上使用GNU awk for gensub(),与其他awks一起使用变量和sub():

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

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

答案 1 :(得分:1)

您可以使用sort -u(唯一)和/作为分隔符,并使用前三个字段作为键。 -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

答案 2 :(得分:1)

如果子目录的长度可变,则此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];
     }'

答案 3 :(得分:1)

使用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命令来代替hdfs dfs -ls -R通过grep传递结果:

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