如何重命名 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}' )
hadoop
测试它是否可以将命令替换为echo
:
$ for f in $files; do echo $f $f.lzo; done
编辑:更新示例以使用awk
而不是sed
更可靠的输出。
“正确”的方法可能是使用HDFS Java API .. 但是对于大多数工作来说,使用 shell 可能更快、更灵活。
当我不得不重命名许多文件时,我正在寻找一个有效的解决方案并偶然发现了这个问题和thi-duong-nguyen的评论,即重命名许多文件非常慢。我为批量重命名操作实现了一个 Java 解决方案,我强烈推荐它,因为它的速度要快几个数量级。基本思想是使用org.apache.hadoop.fs.FileSystem
'srename()
方法:
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://master:8020");
FileSystem dfs = FileSystem.get(conf);
dfs.rename(from, to);
wherefrom
和to
是org.apache.hadoop.fs.Path
对象。最简单的方法是创建要重命名的文件列表(包括它们的新名称)并将此列表提供给 Java 程序。
我已经发布了完整的实现,它从STDIN
. 它在不到 4 秒的时间内重命名了 100 个文件(重命名 7000 个文件需要相同的时间!),而hdfs dfs -mv
前面描述的基于方法需要 4分钟来重命名 100 个文件。
我们创建了一个实用程序来对 HDFS 中的文件进行批量重命名:https ://github.com/tenaris/hdfs-rename 。该工具是有限的,但如果您愿意,您可以使用递归、awk 正则表达式等语法来改进它。