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.