如何在hadoop的新目录中解压缩.gz文件?

Mon*_*ica 16 gzip hadoop hdfs

我在hdfs的文件夹中有一堆.gz文件.我想将所有这些.gz文件解压缩到hdfs中的新文件夹.我该怎么办?

Man*_*lur 30

我可以想到通过3种不同的方式来实现它.

  1. 使用Linux命令行

    以下命令对我有用.

    hadoop fs -cat /tmp/Links.txt.gz | gzip -d | hadoop fs -put - /tmp/unzipped/Links.txt
    
    Run Code Online (Sandbox Code Playgroud)

    我的gzip压缩文件是Links.txt.gz
    输出存储的/tmp/unzipped/Links.txt

  2. 使用Java程序

    Hadoop The Definitve Guide书中,有一节介绍Codecs.在该部分中,有一个程序要使用解压缩输出CompressionCodecFactory.我正在重新生成该代码:

    package com.myorg.hadooptests;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.FileSystem;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.IOUtils;
    import org.apache.hadoop.io.compress.CompressionCodec;
    import org.apache.hadoop.io.compress.CompressionCodecFactory;
    
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.URI;
    
    public class FileDecompressor {
        public static void main(String[] args) throws Exception {
            String uri = args[0];
            Configuration conf = new Configuration();
            FileSystem fs = FileSystem.get(URI.create(uri), conf);
            Path inputPath = new Path(uri);
            CompressionCodecFactory factory = new CompressionCodecFactory(conf);
            CompressionCodec codec = factory.getCodec(inputPath);
            if (codec == null) {
                System.err.println("No codec found for " + uri);
                System.exit(1);
            }
            String outputUri =
            CompressionCodecFactory.removeSuffix(uri, codec.getDefaultExtension());
            InputStream in = null;
            OutputStream out = null;
            try {
                in = codec.createInputStream(fs.open(inputPath));
                out = fs.create(new Path(outputUri));
                IOUtils.copyBytes(in, out, conf);
            } finally {
                IOUtils.closeStream(in);
                IOUtils.closeStream(out);
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    此代码将gz文件路径作为输入.
    您可以执行以下操作:

    FileDecompressor <gzipped file name>
    
    Run Code Online (Sandbox Code Playgroud)

    例如,当我执行我的gzip压缩文件时:

    FileDecompressor /tmp/Links.txt.gz
    
    Run Code Online (Sandbox Code Playgroud)

    我在位置获得了解压缩文件: /tmp/Links.txt

    它将解压缩的文件存储在同一文件夹中.因此,您需要修改此代码以获取2个输入参数:<input file path> and <output folder>.

    一旦你使这个程序工作,你可以编写一个Shell/Perl/Python脚本来为你拥有的每个输入调用这个程序.

  3. 使用Pig脚本

    您可以编写一个简单的Pig脚本来实现此目的.

    我编写了以下脚本,该脚本有效:

    A = LOAD '/tmp/Links.txt.gz' USING PigStorage();
    Store A into '/tmp/tmp_unzipped/' USING PigStorage();
    mv /tmp/tmp_unzipped/part-m-00000 /tmp/unzipped/Links.txt
    rm /tmp/tmp_unzipped/
    
    Run Code Online (Sandbox Code Playgroud)

    运行此脚本时,解压缩的内容存储在临时文件夹中:/tmp/tmp_unzipped.此文件夹将包含

    /tmp/tmp_unzipped/_SUCCESS
    /tmp/tmp_unzipped/part-m-00000
    
    Run Code Online (Sandbox Code Playgroud)

    part-m-00000包含已解压文件.

    因此,我们需要使用以下命令显式重命名它,最后删除/tmp/tmp_unzipped文件夹:

    mv /tmp/tmp_unzipped/part-m-00000 /tmp/unzipped/Links.txt
    rm /tmp/tmp_unzipped/
    
    Run Code Online (Sandbox Code Playgroud)

    因此,如果您使用此Pig脚本,则只需要注意参数化文件名(Links.txt.gz和Links.txt).

    同样,一旦你使这个脚本工作,你可以编写一个Shell/Perl/Python脚本来为你拥有的每个输入调用这个Pig脚本.


tk4*_*421 5

如果您有压缩的文本文件,hadoop fs -text 支持 gzip 以及其他常见的压缩格式(snappy、lzo)。

hadoop fs -text /tmp/a.gz | hadoop fs -put - /tmp/uncompressed_a
Run Code Online (Sandbox Code Playgroud)


Ata*_*ais 5

Bash解决方案

在我的情况下,我不想管道解压缩文件,因为我不确定他们的内容.相反,我想确保将zip文件中的所有文件都提取到HDFS上.

我创建了一个简单的bash脚本.评论应该让你知道发生了什么.下面有一个简短的描述.

#!/bin/bash

workdir=/tmp/unziphdfs/
cd $workdir

# get all zip files in a folder
zips=$(hadoop fs -ls /yourpath/*.zip | awk '{print $8}')
for hdfsfile in $zips
do
    echo $hdfsfile

    # copy to temp folder to unpack
    hdfs dfs -copyToLocal $hdfsfile $workdir

    hdfsdir=$(dirname "$hdfsfile")
    zipname=$(basename "$hdfsfile")

    # unpack locally and remove
    unzip $zipname
    rm -rf $zipname

    # copy files back to hdfs
    files=$(ls $workdir)
    for file in $files; do
       hdfs dfs -copyFromLocal $file $hdfsdir
       rm -rf $file
    done

    # optionally remove the zip file from hdfs?
    # hadoop fs -rm -skipTrash $hdfsfile
done
Run Code Online (Sandbox Code Playgroud)

描述

  1. 获得所有*.zip在文件hdfs目录
  2. 逐个:复制zip到临时目录(在文件系统上)
  3. 拉开拉链
  4. 将所有解压缩的文件复制到zip文件的目录中
  5. 清理

我设法让它使用sub-dir结构来处理每个中的许多zip文件/mypath/*/*.zip.

祝好运 :)