如何将hdfs目录中的所有文件重命名为.lzo
扩展名?.lzo.index
文件不应被重命名。
例如,这个目录列表:
file0.lzo file0.lzo.index file0.lzo_copy_1
可重命名为:
file0.lzo file0.lzo.index file0.lzo_copy_1.lzo
这些文件是lzo压缩的,我需要它们有.lzo
扩展名,以便被Hadoop识别。
如何将hdfs目录中的所有文件重命名为.lzo
扩展名?.lzo.index
文件不应被重命名。
例如,这个目录列表:
file0.lzo file0.lzo.index file0.lzo_copy_1
可重命名为:
file0.lzo file0.lzo.index file0.lzo_copy_1.lzo
这些文件是lzo压缩的,我需要它们有.lzo
扩展名,以便被Hadoop识别。
如果您不想编写Java代码-我认为使用命令行HDFS API是最好的选择:
hadoop fs -mv URI [URI …] <dest>
您可以使用一个简短的一行命令获取路径:
% hadoop fs -ls /user/foo/bar | awk '!/^d/ {print $8}'
/user/foo/bar/blacklist
/user/foo/bar/books-eng
...
awk
将从输出中删除目录...现在,您可以将这些文件放入一个变量中:
% files=$(hadoop fs -ls /user/foo/bar | awk '!/^d/ {print $8}')
并重新命名每个文件..
% for f in $files; do hadoop fs -mv $f $f.lzo; done
你还可以使用awk
来根据其他条件过滤文件。这将删除与正则表达式nolzo
匹配的文件。但是这种方法未经测试。但通过这种方式,您可以编写灵活的过滤器。
% files=$(hadoop fs -ls /user/foo/bar | awk '!/^d|nolzo/ {print $8}' )
尝试使用echo
命令替换hadoop
命令测试其是否有效:
$ for f in $files; do echo $f $f.lzo; done
编辑:更新示例,使用awk
代替sed
以获得更可靠的输出。
可能最好的方法是使用HDFS Java API。然而,对于大多数任务来说,使用shell可能更快、更灵活。
awk
。现在应该更好用了。是时候学习 awk
了 ;) - kei1aeh5quahQu4U当我需要重命名很多文件时,我在寻找高效的解决方案时偶然发现了这个问题和thi-duong-nguyen的评论,即重命名许多文件非常慢。我实现了一个Java解决方案来批量重命名操作,强烈推荐使用,因为它比原来的方法快了几个数量级。基本思想是使用org.apache.hadoop.fs.FileSystem
的rename()
方法:
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://master:8020");
FileSystem dfs = FileSystem.get(conf);
dfs.rename(from, to);
其中from
和to
是org.apache.hadoop.fs.Path
对象。最简单的方法是创建一个包含要重命名的文件列表(包括它们的新名称)并将此列表馈送给Java程序。
我已经发布了完整的实现,它从STDIN
读取这样的映射。它在小于四秒钟内重命名了100个文件(重命名7000个文件需要相同的时间!)而使用之前描述的基于hdfs dfs -mv
的方法需要4分钟才能重命名100个文件。