파일 이름을 무시하고 아카이브에서 파일의 압축을 푸는 방법은 무엇입니까?

파일 이름을 무시하고 아카이브에서 파일의 압축을 푸는 방법은 무엇입니까?

아카이브 내부의 파일 이름이 왜곡되어 있고 ?-s *-s 또는 !-s와 같은 잘못된 파일 시스템 문자가 포함되어 있거나 일반 아카이브 도구가 혼동할 수 있는 매우 긴 파일 및 디렉터리 이름이 포함된 ZIP 및 RAR 아카이브가 여러 개 있습니다. 생성된 파일이 전혀 인식되지 않을 수 있습니다. 콘텐츠만 중요하므로 이러한 아카이브의 파일을 file0, file1, file2 등과 같은 일반적인 이름을 가진 평면 구조의 단일 디렉터리로 추출하고 싶습니다. 가장 쉬운 방법은 무엇입니까?

답변1

Daniel S. Sterling이 작성한 Perl 스크립트https://gist.github.com/eqhmcow/5389877(에서 참조IO::압축해제::압축해제) 필요한 작업을 거의 수행할 것 같습니다.

  • 46행을 다음으로 변경합니다.my $status, $filenumber = 0;
  • 주석 라인 52-54( #각 라인의 시작 부분에 배치)
  • 61번째 줄을 다음으로 변경하세요.my $destfile = "file" . $filenumber++;

이러한 수정 후의 전체 스크립트는 참조용으로 아래에 표시됩니다.

#!/usr/bin/perl
# example perl code, this may not actually run without tweaking, especially on Windows

use strict;
use warnings;

=pod
IO::Uncompress::Unzip works great to process zip files; but, it doesn't include a routine to actually
extract an entire zip file.
Other modules like Archive::Zip include their own unzip routines, which aren't as robust as IO::Uncompress::Unzip;
eg. they don't work on zip64 archive files.
So, the following is code to actually use IO::Uncompress::Unzip to extract a zip file.
=cut

use File::Spec::Functions qw(splitpath);
use IO::File;
use IO::Uncompress::Unzip qw($UnzipError);
use File::Path qw(mkpath);

# example code to call unzip:
unzip(shift);

=head2 unzip
Extract a zip file, using IO::Uncompress::Unzip.
Arguments: file to extract, destination path
    unzip('stuff.zip', '/tmp/unzipped');
=cut

sub unzip {
    my ($file, $dest) = @_;

    die 'Need a file argument' unless defined $file;
    $dest = "." unless defined $dest;

    my $u = IO::Uncompress::Unzip->new($file)
        or die "Cannot open $file: $UnzipError";

    my $status, $filenumber = 0;
    for ($status = 1; $status > 0; $status = $u->nextStream()) {
        my $header = $u->getHeaderInfo();
        my (undef, $path, $name) = splitpath($header->{Name});
        my $destdir = "$dest/$path";

        # unless (-d $destdir) {
        #     mkpath($destdir) or die "Couldn't mkdir $destdir: $!";
        # }

        if ($name =~ m!/$!) {
            last if $status < 0;
            next;
        }

        my $destfile = "file" . $filenumber++;
        my $buff;
        my $fh = IO::File->new($destfile, "w")
            or die "Couldn't write to $destfile: $!";
        while (($status = $u->read($buff)) > 0) {
            $fh->write($buff);
        }
        $fh->close();
        my $stored_time = $header->{'Time'};
        utime ($stored_time, $stored_time, $destfile)
            or die "Couldn't touch $destfile: $!";
    }

    die "Error processing $file: $!\n"
        if $status < 0 ;

    return;
}

1;

관련 정보