Home > OS >  Is it possible to move files within a zip file?
Is it possible to move files within a zip file?

Time:09-16

example.zip/
└── example/
    ├── nice.md
    ├── tree.md
    └── diagram.md

Expected:
example.zip/
├── nice.md
├── tree.md
└── diagram.md

example.zip contains a folder with the same name. In it are files that I want to move to the root of the zip file and remove the empty directory.

I looked at the zip man page. Could not find any flags related to the issue or I could be missing something.

I tried the --copy-entries flag. This create a new zip with selected files from the existing zip but also copy over the folder hierarchy.

zip example.zip "*.md" --copy-entries --out example1.zip

I am trying to write a shell script to do this.

Is it possible to do without extracting the zip?

CodePudding user response:

If you have (or can install) 7z you can make use of the d(delete) and rn(rename) options, eg:

$ mkdir example
$ touch example/{nice.md,tree.md,diagram.md}

$ zip -r example.zip example
  adding: example/ (stored 0%)
  adding: example/diagram.md (stored 0%)
  adding: example/nice.md (stored 0%)
  adding: example/tree.md (stored 0%)

$ unzip -l example.zip
Archive:  example.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  09-15-2022 09:29   example/
        0  09-15-2022 09:29   example/diagram.md
        0  09-15-2022 09:29   example/nice.md
        0  09-15-2022 09:29   example/tree.md
---------                     -------
        0                     4 files

# rename the *.md files first and then delete the directory; if you delete
# the directory first you'll lose all files under the directory; the 7z d/rn 
# commands will generate a lot of output (not shown here)

$ 7z rn example.zip example/nice.md    nice.md
$ 7z rn example.zip example/tree.md    tree.md
$ 7z rn example.zip example/diagram.md diagram.md
$ 7z  d example.zip example

$ unzip -l example.zip
Archive:  example.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  09-15-2022 09:29   diagram.md
        0  09-15-2022 09:29   nice.md
        0  09-15-2022 09:29   tree.md
---------                     -------
        0                     3 files

$ unzip example.zip
Archive:  example.zip
 extracting: diagram.md
 extracting: nice.md
 extracting: tree.md

I'm guessing in OP's real life example the names of the directories and/or files may not be known in advance; the 7z commands do work with bash variables (eg, 7z d "${zipfile}" "${dir_to_delete}"); if OP has issues dynamically processing the contents of a given *zip then I'd recommend asking a new question ...

CodePudding user response:

Good answer. Just to be clear, 7z doesn't do an in-place edit on the zip file when it does the rename/delete. Under the hood it copies the old zip into a temporary file (example.zip.tmp in this instance), renaming & deleting as it does that copy. Then it deletes the original zip file and renames the temporary file, example.zip.tmp back to original filename, example.zip. For the most part this is a perfectly acceptable (and safe) approach.

Main edge condition where it would cause issues is with very large zip files where you are strapped for disk space -- you need to have space available to store the zip file twice when it creates the temporary copy.

  • Related