Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Is there a way to convert a zip archive to a tar archive without extracting to a temporary directory first? (and without writing my own implementation of tar or unzip)

share|improve this question
    
Do you count mounting the zip archive as extracting it to the filesystem? If yes, then you can do it without extraction anything with libarchive but that involves coding. –  Celada Jul 24 at 5:32
    
I think the op looks for something like this superuser.com/questions/325504/… is it the kind of thing you are hoping to achieve? –  vfbsilva Jul 24 at 6:06

2 Answers 2

The tar command deals with file systems. It's input is a list of files that it then reads from a file system (including a lot of metadata). You would need to present the zip file as a file system for the tar command to read it.

A Virtual File System - AVFS will allow any program to look inside archived or compressed files via a standard file system interface via FUSE.

There's some detailed information in the avfs-fuse readme and some distributions have packages for it.

One you have AVFS installed, then you can

mountavfs
cd ~/.avfs/path/to/somefile.zip#
tar -cvf /path/whatever.tar .

AVFS will fill in any information for the file system that is missing from the zip, like file ownership, that tar will pick up.

share|improve this answer

I don't know of any "standard" utility that does so, but when I needed this functionality I wrote the following Python script to go from ZIP to Bzip2 compressed tar archives without extracting anything to disk first:

#! /usr/bin/env python

"""zip2tar """

import sys
import os
from zipfile import ZipFile
import tarfile

def main(ifn, ofn):
    with ZipFile(ifn) as zipf:
        with tarfile.open(ofn, 'w:bz2') as tarf:
            for zip_info in zipf.infolist():
                #print zip_info.filename, zip_info.file_size
                tar_info = tarfile.TarInfo(name=zip_info.filename)
                tar_info.size = zip_info.file_size
                tar_info.mtime = time.mktime(list(zip_info.date_time) +
                                         [-1, -1, -1])
                tarf.addfile(
                    tarinfo=tar_info,
                    fileobj=zipf.open(zip_info.filename)
                )

input_file_name = sys.argv[1]
output_file_name = os.path.splitext(input_file_name)[0] + '.tar.bz2'

main(input_file_name, output_file_name)

Just save it to zip2tar and make it executable or save it to zip2tar.py and run python zip2tar.py. Provide the ZIP filename as an argument to the script, the output filename for xyz.zip will be xyz.tar.bz2.

The Bzip2 compressed output is normally much smaller than the zip file because the latter doesn't use compression patterns over multiple files, but there is also less chance of recovering later file if something in the Bzip2 file is wrong.

If you don't want the output compressed, remove :bz2 and .bz2 from the code.

share|improve this answer
1  
Nice one. It looks like the script does not make any attempt to copy metadata such as file modification time and permissions across the archive format change, but I think you could add that quite easily. –  Celada Jul 24 at 6:11
    
@Celada I added the file modification time (missed that while copy and pasting from my orginal code), I am not sure if the ZIP standard actually has permissions, AFAIK (modern) tar is more complete in that respect with ZIP more being Windows oriented. –  Anthon Jul 24 at 6:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.