Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 递归搜索grep_Linux_Grep_Hdfs - Fatal编程技术网

Linux 递归搜索grep

Linux 递归搜索grep,linux,grep,hdfs,Linux,Grep,Hdfs,我正试图通过HDF搜索拼花地板文件并将其列出。我用这个,效果很好。它查看了/sources.works\u dbo中的所有子目录,并提供了所有拼花地板文件: hdfs dfs -ls -R /sources/works_dbo | grep ".*\.parquet$" 但是,;我只想返回它在每个子目录中遇到的第一个文件,这样每个子目录只显示在输出中的一行上。假设我有这个: sources/works_dbo/test1/file1.parquet sources/works_dbo/tes

我正试图通过HDF搜索拼花地板文件并将其列出。我用这个,效果很好。它查看了
/sources.works\u 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

您可以使用
排序-u
(唯一),将
/
作为分隔符,并使用前三个字段作为键。
-s
选项(“稳定”)确保保留的文件是每个子目录遇到的第一个文件

对于此输入

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

如果子目录长度可变,此
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];
     }'
上面将GNU awk用于gensub(),对于其他awk,您将使用变量和sub()

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

使用Perl:

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

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

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


这真的很优雅。
awk '{path=$0; sub(/[^/]+$/,"",path)} !seen[path]++'
hdfs dfs -ls -R /sources/works_dbo | grep '.*\.parquet$' | \
  perl -MFile::Basename -nle 'print unless $h{ dirname($_) }++'
hdfs dfs -find /sources/works_dbo -name '*.parquet'