descomprimir archivos (zip, tar, tag.gz) con ruby

Quiero descomprimir una gran cantidad de archivos zip. ¿Hay algún módulo o script que compruebe qué formato es el archivo zip y lo descomprime? Esto debería funcionar en Linux, no me importan otros sistemas operativos.

Para extraer archivos de un archivo .tar.gz puede usar los siguientes métodos de paquetes distribuidos con Ruby:

require 'rubygems/package' require 'zlib' tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open('Path/To/myfile.tar.gz')) tar_extract.rewind # The extract has to be rewinded after every iteration tar_extract.each do |entry| puts entry.full_name puts entry.directory? puts entry.file? # puts entry.read end tar_extract.close 

Cada entrada de tipo Gem :: Package :: TarReader :: Entry apunta a un archivo o directorio dentro del archivo .tar.gz.

Se puede usar un código similar (reemplace Reader with Writer) para escribir archivos en un archivo .tar.gz.

La forma más fácil es probablemente usar Zlib

Zlib es una biblioteca de Ruby. Lo que sigue es un progtwig simple para tomar un archivo comprimido de una URL en particular, descomprimirlo y pegar sus contenidos en la pantalla.

 require 'zlib' require 'open-uri' uri = "www.somedomain.com/filename.gz" source = open(uri) gz = Zlib::GzipReader.new(source) result = gz.read puts result 

Espero que esto ayude.

Si bien la respuesta de Florian es correcta, no toma en cuenta los LongLinks de tar (prueba extrayendo jdk-7u40-linux-i586.tar.gz de oracle: P). El siguiente código debería poder hacer esto:

 require 'rubygems/package' require 'zlib' TAR_LONGLINK = '././@LongLink' tar_gz_archive = '/path/to/archive.tar.gz' destination = '/where/extract/to' Gem::Package::TarReader.new( Zlib::GzipReader.open tar_gz_archive ) do |tar| dest = nil tar.each do |entry| if entry.full_name == TAR_LONGLINK dest = File.join destination, entry.read.strip next end dest ||= File.join destination, entry.full_name if entry.directory? File.delete dest if File.file? dest FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false elsif entry.file? FileUtils.rm_rf dest if File.directory? dest File.open dest, "wb" do |f| f.print entry.read end FileUtils.chmod entry.header.mode, dest, :verbose => false elsif entry.header.typeflag == '2' #Symlink! File.symlink entry.header.linkname, dest end dest = nil end end 

Draco, gracias por tu fragmento . Algunos TAR codifican directorios como rutas que terminan con ‘/’ – vea esta Wiki. Examlple tar es Oracle Server JRE 7u80 para Windows . Esto funcionará para ellos:

 require 'fileutils' require 'rubygems/package' require 'zlib' TAR_LONGLINK = '././@LongLink' Gem::Package::TarReader.new( Zlib::GzipReader.open tar_gz_archive ) do |tar| dest = nil tar.each do |entry| if entry.full_name == TAR_LONGLINK dest = File.join destination, entry.read.strip next end dest ||= File.join destination, entry.full_name if entry.directory? || (entry.header.typeflag == '' && entry.full_name.end_with?('/')) File.delete dest if File.file? dest FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false elsif entry.file? || (entry.header.typeflag == '' && !entry.full_name.end_with?('/')) FileUtils.rm_rf dest if File.directory? dest File.open dest, "wb" do |f| f.print entry.read end FileUtils.chmod entry.header.mode, dest, :verbose => false elsif entry.header.typeflag == '2' #Symlink! File.symlink entry.header.linkname, dest else puts "Unkown tar entry: #{entry.full_name} type: #{entry.header.typeflag}." end dest = nil end end end