bash 解压 ZIP 文件并提取未知文件夹名称的内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4301786/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:00:15  来源:igfitidea点击:

Unzip ZIP file and extract unknown folder name's content

bashzipunzip

提问by siliconpi

My users will be zipping up files which will look like this:

我的用户将压缩如下所示的文件:

TEMPLATE1.ZIP
   |--------- UnknownName
                   |------- index.html
                   |------- images
                               |------- image1.jpg

I want to extract this zip file as follows:

我想按如下方式解压缩这个 zip 文件:

/mysite/user_uploaded_templates/myrandomname/index.html
/mysite/user_uploaded_templates/myrandomname/images/image1.jpg

My trouble is with UnknownName - I do not know what it is beforehand and extracting everything to the "base" level breaks all the relative paths in index.html

我的问题是 UnknownName - 我事先不知道它是什么,将所有内容提取到“基本”级别会破坏 index.html 中的所有相对路径

How can I extract from this ZIP file the contentsof UnknownName?

如何从此 ZIP 文件中提取UnknownName的内容

Is there anythingbetter than:

什么比:

1. Extract everything
2. Detect which "new subdidrectory" got created
3. mv newsubdir/* .
4. rmdir newsubdir/

If there is more than one subdirectory at UnknownName level, I can reject that user's zip file.

如果在 UnknownName 级别有多个子目录,我可以拒绝该用户的 zip 文件。

回答by Paused until further notice.

I think your approach is a good one. Step 2 could be improved my extracting to a newly created directory (later deleted) so that "detection" is trivial.

我认为你的方法是一个很好的方法。第 2 步可以改进我提取到新创建的目录(后来删除),以便“检测”是微不足道的。

# Bash (minimally tested)
tempdest=$(mktemp -d)
unzip -d "$tempdest" TEMPLATE1.ZIP
dir=("$tempdest"/*)
if (( ${#dir[@]} == 1 )) && [[ -d $dir ]]
    # in Bash, etc., scalar $var is the same as ${var[0]}
    mv "$dir"/* /mysite/user_uploaded_templates/myrandomname
else
    echo "rejected"
fi
rm -rf "$tempdest"

回答by SiegeX

The other option I can see other than the one you suggested is to use the unzip -jflag which will dump all paths and put all files into the current directory. If you know for certain that each of your TEMPLATE1.ZIPfiles includes an index.htmland *.jpgfiles then you can just do something like:

除了您建议的选项之外,我可以看到的另一个选项是使用该unzip -j标志,该标志将转储所有路径并将所有文件放入当前目录。如果您确定您的每个TEMPLATE1.ZIP文件都包含一个index.html*.jpg文件,那么您可以执行以下操作:

destdir=/mysite/user_uploaded_templates/myrandomname
unzip -j -d "$destdir"
mkdir "${destdir}/images"
mv "${destdir}/*.jpg" "${destdir}/images"

It's not exactly the cleanest solution but at least you don't have to do any parsing like you do in your example. I can't seem to find any option similar to patch -p#that lets you specify the path level.

这并不是最干净的解决方案,但至少您不必像在示例中那样进行任何解析。我似乎找不到任何类似于patch -p#让您指定路径级别的选项。

回答by David W.

Each zipand unzipcommand differs, but there's usually a way to list the file contents. From there, you can parse the output to determine the unknown directory name.

每个zipunzip命令都不同,但通常有一种方法可以列出文件内容。从那里,您可以解析输出以确定未知的目录名称。

On Windows, the 1996 Wales/Gaily/van der Linden/Rommel version it is unzip -l.

在 Windows 上,1996 Wales/Gaily/van der Linden/Rommel 版本是unzip -l.

Of course, you could just simply allow the unzip to unzip the files to whatever directory it wants, then use mvto rename the directory to what you want it as.

当然,您可以简单地允许解压缩将文件解压缩到它想要的任何目录,然后使用mv将目录重命名为您想要的。

$tempDir = temp.$$
mv $zipFile temp.$$
cd $tempDir
unzip $zipFile
$unknownDir = *   #Should be the only directory here
mv $unknownDir $whereItShouldBe
cd ..
rm -rf $tempDir

It's always a good idea to create a temporary directory for these types of operations in case you end up running two instances of this command.

为这些类型的操作创建一个临时目录总是一个好主意,以防您最终运行此命令的两个实例。