zip 文件f.zip
包含一堆带有目录的文件。
A/B
A/B/C
A/B/C/D
..
A/B/C/D/and/some/more/dirs
A/B2
现在我只对 C/D 下面的树感兴趣。我可以unzip f.zip */D/* -d .
将 D 下的所有内容(假设 D 是唯一序列)解压到当前目录,包括 A/B/C,但是我希望 D 成为解压缩操作的根目录。当然,我可以将 D 移动到我当前的工作目录,但我认为这是作弊。
手册页和谷歌都没有透露解决方案,但也许我忽略了,也许有一个比移动更好的解决方案。
哦我的平台是 mac os x 10.8.prettyup2date
答案1
通过解压缩手册页:
-j junk paths. The archive's directory structure is not recreated;
all files are deposited in the extraction directory (by default,
the current one).
所以:
unzip -d D -j f.zip */D/*
将其全部提取到名为 D 的文件夹,但没有目录结构(请注意,这会将 D 子目录中的文件提取到顶级输出 D 文件夹中)。
编辑OP 希望将文件结构保留在 D 文件夹下。
unzip -l f.zip | grep 'A/B/C/D' | \
perl -ple 's/\s+\d+\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+(.*)$/$1/' | \
while read file
do
unzip -j -d "$(echo $file | sed 's:A/B/C/\(.*\)/.*:\1:g')" f.zip "$file"
done
每个步骤的部分:
unzip -l f.zip
获取 f.zip 中的文件列表
grep 'A/B/C/D'
grep 出显示目标目录下文件的行
perl -ple 's/\s+\d+\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+(.*)$/$1/'
使用 perl 获取该匹配行上的文件名(我的 sed-fu 不如 Stephane 的那么好,所以我将使用 perl!),注意这处理文件名中的空格:)
while read file
do
循环遍历上述命令生成的文件并将其分配给$file
unzip -j -d "$(echo $file | sed 's:A/B/C/\(.*\)/.*:\1:g')" f.zip "$file"
解压缩目标$file
,并丢弃其路径,到目标目录
echo $file | sed 's:A/B/C/\(.*\)/.*:\1:g'
它从文件名中删除前导 A/B/C/ 路径,请注意它被包含在 $() 中(a Command substitution
,有关更多详细信息,请参阅 bash ),并且该命令替换位于双引号内以保留空格(并实际评估$()
)。
done
完成循环。
这实际上对 A/B/C 下匹配的每个文件运行解压缩操作:
unzip -j -d "D" f.zip "A/B/C/D/"
unzip -j -d "D" f.zip "A/B/C/D/b"
unzip -j -d "D" f.zip "A/B/C/D/e"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/b"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/e"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/d"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/c"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/a"
unzip -j -d "D" f.zip "A/B/C/D/d"
unzip -j -d "D" f.zip "A/B/C/D/f"
如果您运行此命令来提取到已经存在的文件结构中,您将需要-o
向override
现有文件添加额外的内容(或者破坏文件的第一个解压缩操作将提示 a replace D/b? [y]es, [n]o, [A]ll, [N]one, [r]ename: extracting: D/b
,然后炸掉)。如果您需要该提示,那么您将不得不使用另一种不使用 read 和 的循环方法还处理空格(for $( ... )
将导致测试失败)。如果您需要这样做,我会将其作为练习留给您来解决!
答案2
将 zip 挂载为目录。你可以通过以下方式做到这一点保险丝,由普通程序而不是内核驱动程序实现的文件系统驱动程序的通用框架。安装OSX保险丝(OSX 上的通用 FUSE 支持),然后保险丝拉链(用于 zip 存档的 FUSE 驱动程序)。安装必要的软件后,安装存档:
mkdir /tmp/myzip
fuse-zip f.zip /tmp/myzip
您现在可以像访问目录一样访问 zip 中的文件。要提取A/B/C/D
,请复制它:
cp -Rp /tmp/myzip/A/B/C/D /some/where
完成后将拉链卸下。
fusermount -u /tmp/myzip
rmdir /tmp/myzip
如果您想跳过预安装的软件,我认为您必须解压缩A/B/C/D
然后移动目录。