Linux 递归搜索grep
我正试图通过HDF搜索拼花地板文件并将其列出。我用这个,效果很好。它查看了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
/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
使Perl为每个输入行应用通过-n
传递的表达式李>-e
保留行终止符李>-l
$是保留当前读取行的默认变量李>
返回由dirname($)
$指定的路径的目录部分李>
是一个散列,其中键是目录名,值是整数0、1、2等李>$h
- 该行将打印到标准输出,除非在以前的迭代中看到目录名,即哈希值
为非零$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'