客观的:
a.zip
使用命令unzip
on展开存档后Ubuntu 12.10
,将展开到的文件夹的名称分配a.zip
给bash
变量v
。
a.zip
假设并保证扩展到单个文件夹,而不是多个文件夹。
例子:
如果unzip a.zip
扩展到文件夹./foo/
,echo $v
应该返回foo
。
我的环境:
GNU/Linux (kernel 3.5.0-25-generic)
Ubuntu 12.10
bash v4.2.37(1)-release
UnZip 6.00 of 20 April 2009, by Debian. Original by Info-ZIP.
目前的解决方法我是不高兴with: Expand via unzip -d bar a.zip
thenv=$(ls -1 bar)
给出了正确的结果,但会弄乱文件系统。
答案1
干得好:
v=$(unzip a.zip | grep -m1 'creating:' | cut -d' ' -f5-)
解释
$(...)
是一个捕获外壳。它捕获其中命令的输出并像变量一样替换它们。- 该命令的输出
unzip
通过管道传输到grep
,它传递参数-m1
以使其仅返回第一个结果和 text ,这是创建目录时打印到 stdout 的creating:
文本的一部分。打印到 stdout,这是通过管道传输的。unzip
grep
creating: foo/
cut
cut
用于打印第二列之后的所有列(用空格分隔)。我们指定从 5 到行尾,因为该单词creating:
带有一些空格前缀。我们希望使用所有列直到行尾,以防目录名称中包含空格。最终的输出是foo/
.
答案2
- 您可以用来
unzip -l
列出存档的内容并解析输出 - 或者您可以列出该目录,再次提取列出该目录的arcive,然后使用比较两个列表
diff
答案3
这AVFS文件系统提供了文件系统的视图,其中每个存档文件都/path/to/foo.zip
可以作为目录进行访问~/.avfs/path/to/foo.zip#
。
mountavfs
ls ~/.avfs$PWD/foo.zip\#
如果该ls
命令显示单个目录,则解压缩 zip 文件将创建该目录并在其下创建文件。请注意,zip 文件可能会也可能不会以这种方式组织。
这是一个检查您的假设的代码片段,并设置dir
为目录名称(如果适用)。警告:如果 zip 文件包含名称以 a 开头的文件.
(点文件),它们将被忽略。
zip_directory_name () {
case $1 in
/*) ;;
*) set "$PWD/$1";;
esac
cd ~/.avfs${1}\# || exit 2
set -- *
if [ $# -eq 1 ] && [ -d "$1" ]; then
printf %s "$1"
else
return 1 # more than one top-level file, or a single non-directory
fi
}
dir=$(zip_directory_name foo.zip) || exit $?
答案4
如果您愿意,可以对您的解决方法不满意,但这实际上是正确的解决方案。
d="`mktemp -d`"
unzip -d "$d" "$zipfile"
v="`basename "$d"/*`"
mv "$d"/"$v" "$v"
rmdir "$d"
echo "$v"
这很冗长,但是 - 只要 zip 文件中确实只有一个目录(您可能应该首先检查该目录) - 它是可靠的。
ls
并且grep
不太可靠,因为它取决于输出的样子。在不同的语言环境中,可能没有任何“creating:”字符串。在 unzip 的下一个版本中,它可能会因任何原因而更改。