AFAIK zip
doesn't have an option for that, but tar
does have:
--transform, --xform EXPRESSION
use sed replace EXPRESSION to transform file names.
So:
$ mkdir node_modules
$ touch node_modules/file{1..3}
$ tree node_modules/
node_modules/
├── file1
├── file2
└── file3
0 directories, 3 files
$
$ tar czf test.tgz --transform 's|^|nodejs/|' node_modules/
$ tar -tf test.tgz
nodejs/node_modules/
nodejs/node_modules/file2
nodejs/node_modules/file3
nodejs/node_modules/file1
$
$ tar xf test.tgz
$ tree nodejs/
nodejs/
└── node_modules
├── file1
├── file2
└── file3
1 directory, 3 files
If however your end result must be a zip
archive then you can use tar
without compression to save time and resources then extract the archive and compress it with zip
afterwards ... Or you can use a function that will automatically do this for you like this:
my_zip () {
p="$1" # First argument "archive prefix directory name"
d="$2" # Second argument "source directory name"
z="$3" # Third argument "result ZIP archive name without .zip"
[ -e "$p" -o -e "${z}.zip" ] && return "Prefix directory name: $p Or target zip file name: ${z}.zip exist in PWD, cannot continue"
tmp="$(mktemp)"
tar cf "$tmp" --transform "s|^|$p/|" "$d"
tar xf "$tmp"
zip -rq "${z}.zip" "$p"
rm "$tmp"
rm -r "$p"
}
Then use the function by its name my_zip
passing properly quoted arguments "prefix"
, "source_directory"
and "zip_archive_name"
in that order like so:
$ my_zip "nodejs2" "node_modules" "test2"
$ unzip -l test2.zip
Archive: test2.zip
Length Date Time Name
--------- ---------- ----- ----
0 2023-04-24 17:11 nodejs2/
0 2023-04-24 16:58 nodejs2/node_modules/
0 2023-04-23 19:51 nodejs2/node_modules/file2
0 2023-04-23 19:51 nodejs2/node_modules/file3
0 2023-04-23 19:51 nodejs2/node_modules/file1
--------- -------
0 5 files
$
$ unzip -q test2.zip
$ tree nodejs2/
nodejs2/
└── node_modules
├── file1
├── file2
└── file3
1 directory, 3 files