为 zip 中的每个文件添加前缀文件夹名称

为 zip 中的每个文件添加前缀文件夹名称

我想递归地压缩所有文件但在前面添加一些前缀文件夹。

我试过:

zip -rq test.zip node_modules --prefix nodejs/

但出现错误:zip error: Invalid command arguments (long option 'prefix' not supported)

还尝试了--transform,但它似乎在 Linux 上也不起作用。

我的目标是所有带有子文件夹的文件node_modules/*都应位于nodejs/node_modules/*zip 文件内的路径中

目前我正在使用一种困难的方法来实现它:

mkdir nodejs
mv node_modules nodejs/
zip -rq ./$OUTPUT_DIR/dep-$DEP_VERSION.zip nodejs
mv nodejs/node_modules ./
rm -r nodejs

但我正在寻找更优雅的解决方案。有什么建议吗?

答案1

AFAIKzip没有这个选项,但是tar确实有:

--transform, --xform 表达式
  使用 sed 替换 EXPRESSION 来转换文件名。

所以:

$ 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

但是,如果您的最终结果必须是一个zip档案,那么您可以使用tar不压缩来节省时间和资源,然后提取档案并使用压缩它zip...或者您可以使用一个函数来自动为您执行此操作,如下所示:

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"
}

然后通过函数名称my_zip传递正确引用的参数"prefix""source_directory"并按"zip_archive_name"如下顺序使用:

$ 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

相关内容