在Hadoop中批量重命名

6

如何将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 API还是命令行工具? - Thomas Jungblut
最好使用命令行工具,谢谢。 - beefyhalo
@beefyhalo,我们创建了一个命令行工具,你可以在我们的回答中找到它。 - Ameba Spugnosa
3个回答

15

如果您不想编写Java代码-我认为使用命令行HDFS API是最好的选择:

Hadoop中的mv

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将从输出中删除目录...现在,您可以将这些文件放入一个变量中:

注:本翻译保留了原文中的代码标记和HTML标签。
% 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可能更快、更灵活。


这绝对是有帮助的,尽管你的切割方法不能可靠地工作,而且sed给我报错。 - beefyhalo
我更新了答案,使用了 awk。现在应该更好用了。是时候学习 awk 了 ;) - kei1aeh5quahQu4U
2
这个可以用,但如果你要重命名成千上万的文件,它会非常慢。 - Thi Duong Nguyen
你可以尝试使用GNU Parallel或类似工具并行执行for循环来提高速度。使用Java Hadoop-API可能会更快。 - kei1aeh5quahQu4U
在上面的awk命令后添加“| awk -F'/' '{print $NF}'”,以剥离前导目录名称。 - Glenn Strycker
显示剩余5条评论

9

当我需要重命名很多文件时,我在寻找高效的解决方案时偶然发现了这个问题和thi-duong-nguyen的评论,即重命名许多文件非常慢。我实现了一个Java解决方案来批量重命名操作,强烈推荐使用,因为它比原来的方法快了几个数量级。基本思想是使用org.apache.hadoop.fs.FileSystemrename()方法:

Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://master:8020");
FileSystem dfs = FileSystem.get(conf);
dfs.rename(from, to);

其中fromtoorg.apache.hadoop.fs.Path对象。最简单的方法是创建一个包含要重命名的文件列表(包括它们的新名称)并将此列表馈送给Java程序。

已经发布了完整的实现,它从STDIN读取这样的映射。它在小于四秒钟内重命名了100个文件(重命名7000个文件需要相同的时间!)而使用之前描述的基于hdfs dfs -mv的方法需要4分钟才能重命名100个文件。


我也遇到了这个问题。使用像提到的Java方法很明显更快——我想它是使用单一连接而不是为每个文件创建和销毁一个唯一连接。 然而,我想知道是否有人能够在EMR上运行此类代码。 我似乎无法让它工作。 根据我在这里看到的(https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-hadoop-script.html),我必须在集群上构建代码。 但这似乎过于繁琐,只是为了移动一些文件。 有人能够在EMR上运行这个吗? - Zack

2
我们创建了一个工具来批量重命名HDFS中的文件:https://github.com/tenaris/hdfs-rename。这个工具有一定的限制,但如果你想的话,可以通过递归、awk正则语法等来改进它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接