décompressez (zip, tar, tag.gz fichiers) avec ruby

je veux décompresser beaucoup de fichiers zip. Est-il un module ou d'un script qui vérifie le format du fichier zip est et décompresse? Cela devrait fonctionner sous Linux, je me fiche des autres OS.

26
demandé sur Adi Inbar 2009-05-13 13:05:29

4 réponses

pour extraire des fichiers de A.tar.vous pouvez utiliser les méthodes suivantes À partir des paquets distribués avec 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

Chaque entrée de type Gem::Package::TarReader::Entry pointe vers un fichier ou d'un répertoire à l'intérieur de l' .tar.fichier gz.

code similaire peut être utilisé (remplacer lecteur avec écrivain) pour écrire des fichiers à A.tar.fichier gz.

27
répondu Florian Feldhaus 2013-08-21 17:34:20

la façon la plus facile est probablement D'utiliser Zlib

Zlib est une bibliothèque de rubis. Ce qui suit est un programme simple pour saisir un fichier zippé à partir d'une URL particulière, décompresser, et coller son contenu à l'écran.

require 'zlib' 
require 'open-uri'

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

j'espère que cela aidera.

28
répondu Community 2011-10-28 17:57:05

bien que Florian's answer soit juste, il ne prend pas en compte tar LongLinks (essayer d'extraire jdk-7u40-linux-i586.tar.gz de oracle: P ). Le code suivant devrait pouvoir le faire:

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
11
répondu Draco Ater 2017-05-23 11:54:35

Draco, thx pour vous extrait de . Certains tars encodent les répertoires comme des chemins se terminant par ' / ' - voir ce "Wiki 151930920". EXAML tarple est Oracle Server JRE 7u80 pour Windows . Cela leur conviendra:

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
2
répondu TomCZ 2017-05-23 11:54:35