Как распаковать.файлы gz в новом каталоге в hadoop?
У меня куча .GZ файлы в папке в hdfs. Я хочу расстегнуть все это .GZ файлы в новую папку в hdfs. Как мне это сделать?
5 ответов
я могу думать о достижении этого через 3 разных способа.
-
использование командной строки Linux
следующая команда работала на меня.
hadoop fs -cat /tmp/Links.txt.gz | gzip -d | hadoop fs -put - /tmp/unzipped/Links.txt
мой gzipped файл
Links.txt.gz
Вывод сохраняется в/tmp/unzipped/Links.txt
-
использование программы 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); } } }
этот код принимает путь файла gz в качестве входных данных.
Вы можете выполнить это:FileDecompressor <gzipped file name>
например, когда я выполнял для своего файла gzipped:
FileDecompressor /tmp/Links.txt.gz
я получил распакованный файл в месте:
/tmp/Links.txt
он хранит распакованный файл в той же папке. Поэтому вам нужно изменить этот код, чтобы принять 2 входных параметра:
<input file path> and <output folder>
.после того, как вы чтобы эта программа работала, вы можете написать сценарий Shell/Perl/Python для вызова этой программы для каждого из ваших входов.
-
использование сценария свиньи
вы можете написать простой скрипт Свиньи для достижения этого.
я написал следующий скрипт, который работает:
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/
при запуске этого скрипта распакованное содержимое сохраняется во временной папке:
/tmp/tmp_unzipped
. Эта папка будет contain/tmp/tmp_unzipped/_SUCCESS /tmp/tmp_unzipped/part-m-00000
на
part-m-00000
содержит распакованный файл.следовательно, нам надо явно переименовать его, используя следующую команду и, наконец, удалить :
mv /tmp/tmp_unzipped/part-m-00000 /tmp/unzipped/Links.txt rm /tmp/tmp_unzipped/
Итак, если вы используете этот скрипт Pig, вам просто нужно позаботиться о параметризации имени файла (ссылки.формат txt.gz и ссылки.формат txt.)
опять же, как только вы получите этот скрипт, вы можете написать сценарий оболочки/Perl/Python, чтобы вызвать этот скрипт Свиньи для каждого из входы у вас есть.
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 }')
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
описание
- показать все
*.zip
файлыhdfs
реж.--16--> - один-на-один: скопировать
zip
в temp dir (в файловой системе) - распакуйте
- скопировать все извлеченные файлы в каталог zip-архив
- очистка
мне удалось заставить его работать со структурой sub-dir для многих zip-файлов в каждом, используя /mypath/*/*.zip
.
удачи :)
если у вас есть сжатые текстовые файлы, hadoop fs-text поддерживает gzip наряду с другими распространенными форматами сжатия (snappy, lzo).
hadoop fs -text /tmp/a.gz | hadoop fs -put - /tmp/uncompressed_a
вы можете сделать это с помощью hive (предполагая, что это текстовые данные).
create external table source (t str) location '<directory_with_gz_files>';
create external table target (t str) location '<target_dir>';
insert into table target select * from source;
данные будут распакованы в новый набор файлов.
Если вы не хотите изменять имена и если у вас достаточно памяти на узле, где вы работаете, вы можете сделать это.
hadoop fs -get <your_source_directory> <directory_name>
It will create a directory where you run hadoop command. cd to it and gunzip all the files
cd ..
hadoop fs -moveFromLocal <directory_name> <target_hdfs_path>
Hadoop на базе FileUtil
класс unTar()
и unZip()
методы для достижения этого. The unTar()
метод будет работать на .tar.gz
и .tgz
файлов, а также. К сожалению, они работают только с файлами в локальной файловой системе. Вам придется использовать один из того же класса copy()
методы копирования В и из любых распределенных файловых систем, которые необходимо использовать.