我有数百个目录,其中有一些 zip 文件。现在这些 zip 文件中有名为 abc.jpg 的图像。 zip 文件可能位于任何文件夹或任何子文件夹中,因此很难将它们全部提取到一处。
我只是想收集这些图像文件。这可能吗?
答案1
我曾经需要类似的东西来在一堆 zip 文件中查找类文件。这里是:
#!/bin/bash
function process() {
while read line; do
if [[ "$line" =~ ^Archive:\s*(.*) ]] ; then
ar="${BASH_REMATCH[1]}"
#echo "$ar"
else
if [[ "$line" =~ \s*([^ ]*abc\.jpg)$ ]] ; then
echo "${ar}: ${BASH_REMATCH[1]}"
fi
fi
done
}
find . -iname '*.zip' -exec unzip -l '{}' \; | process
现在您只需添加一行即可提取文件并可能移动它们。我不确定你到底想做什么,所以我把它留给你。
答案2
如果您的 Unix 版本支持保险丝(Linux、*BSD、OSX、Solaris 均如此)、挂载AVFS透明地访问档案。该命令mountavfs
创建整个文件系统的视图,以 为根~/.avfs
,其中存档文件有一个关联的目录,其中包含存档中的目录和文件。例如,如果您foo.zip
在当前目录中,则以下命令大致相当于unzip -l foo.zip
:
mountavfs # needs to be done once and for all
find ~/.avfs$PWD/foo.zip\# -ls
因此,要循环当前目录下 zip 文件中包含的所有图像并将它们复制到/destination/directory
(在发生冲突时会出现提示):
find ~/.avfs"$PWD" -name '*.zip' -exec sh -c '
find "${0}#" -name "*.jpg" -exec cp -ip {} "$1" \;
' {} /destination/directory \;
在 zsh 中:
cp -ip ~/.avfs$PWD/**/*.zip(e\''REPLY=($REPLY\#/**/*.jpg(N))'\') /destination/directory
解构:~/.avfs$PWD/**/*.zip
展开到当前目录下zip文件的AVFS视图。 glob 限定符e
用于修改 glob 的输出:…/*.zip(e\''REPLY=$REPLY\#'\')
只会将 a 附加#
到每个匹配项。将每个匹配项转换为目录中的文件REPLY=($REPLY\#/**/*.jpg(N))
数组。.jpg
.zip#
答案3
我假设您有新版本的 Bash,所以您应该能够使用它:
shopt -s globstar
for path in topdir/**/*.zip
do
unzip "$path" '.*abc.jpg'
done
答案4
我们开工吧!可悲的是,现有的答案在各种明显的方面都存在缺陷——包括这里和其他地方的答案。流行的重复。
这接受的答案,例如,是 Bash 特定的 (那很糟)并将所需的搜索模式硬编码为一次性的 10 行 shell 函数(那就更糟糕了)。这下一个最受好评的答案利用基于 FUSE 的伪文件系统(这显然是疯狂的)。同样,上述重复项中得票最高的答案产生不明确的、非人类可读的输出(只是...呃)。
我对杰克的干瘪不以为然。
工作代码或者它没有发生
一个新的竞争者已经进入擂台:
# str find_in_zip(str regex, str zip_filename1, ...)
#
# Find all paths contained in any zip-formatted archives with the passed
# filenames such that the relative pathnames of these paths in these
# archives match the passed extended regular expression.
function find_in_zip() {
(( $# >= 2 )) || {
echo 'Expected one extended regular expression and one or more zip filenames.' 1>&2
return 1
}
# Localize and remove the passed regex from the argument list.
local regex="${1}" zip_filename
shift
# For each passed zip filename...
for zip_filename in "${@}"; do
# Print the name of this filename for disambiguity.
echo "${zip_filename}:"
# Print all paths in this file matching this regex.
command unzip -l "${zip_filename}" |
command grep --extended-regexp --color=always "${regex}"
# Page the above output for readability.
done | less --RAW-CONTROL-CHARS
}
为了可用性,使用与 完全相同的签名来调用该函数grep
。也就是说,该函数首先接受要搜索的正则表达式,然后接受一个或多个 zip 文件名的可变参数序列。
同样,该功能已在 Bash 和 zsh 下进行了测试。将上述代码添加到 或 中~/.bashrc
,~/.zshrc
伟大的 zip 文件荣耀将属于您,最好set -e
启用以实现理智和严格。
例子或它没有发生
为了演示,让我们找到嵌入的所有类的集合I2P在 Gentoo Linux 下安装的 JAR 文件,其名称以七个大写字符开头,后跟一个小写字符 -只是因为:
$ find_in_zip '/[A-Z]{7}[a-z]' /usr/share/i2p/lib/*.jar
/usr/share/i2p/lib/addressbook.jar:
/usr/share/i2p/lib/BOB.jar:
/usr/share/i2p/lib/commons-el.jar:
/usr/share/i2p/lib/desktopgui.jar:
/usr/share/i2p/lib/i2p.jar:
568 01-16-2020 00:20 freenet/support/CPUInformation/AMDCPUInfo.class
236 01-16-2020 00:20 freenet/support/CPUInformation/VIACPUInfo.class
/usr/share/i2p/lib/i2psnark.jar:
/usr/share/i2p/lib/i2ptunnel.jar:
/usr/share/i2p/lib/jasper-compiler.jar:
/usr/share/i2p/lib/jasper-runtime.jar:
/usr/share/i2p/lib/jetty-continuation.jar:
/usr/share/i2p/lib/jetty-deploy.jar:
/usr/share/i2p/lib/jetty-http.jar:
/usr/share/i2p/lib/jetty-i2p.jar:
/usr/share/i2p/lib/jetty-io.jar:
/usr/share/i2p/lib/jetty-java5-threadpool.jar:
/usr/share/i2p/lib/jetty-rewrite-handler.jar:
/usr/share/i2p/lib/jetty-security.jar:
/usr/share/i2p/lib/jetty-servlet.jar:
/usr/share/i2p/lib/jetty-servlets.jar:
/usr/share/i2p/lib/jetty-sslengine.jar:
/usr/share/i2p/lib/jetty-start.jar:
/usr/share/i2p/lib/jetty-util.jar:
/usr/share/i2p/lib/jetty-webapp.jar:
/usr/share/i2p/lib/jetty-xml.jar:
/usr/share/i2p/lib/jstl.jar:
/usr/share/i2p/lib/mstreaming.jar:
/usr/share/i2p/lib/org.mortbay.jetty.jar:
/usr/share/i2p/lib/org.mortbay.jmx.jar:
/usr/share/i2p/lib/routerconsole.jar:
/usr/share/i2p/lib/router.jar:
5598 01-16-2020 00:20 org/cybergarage/upnp/ssdp/HTTPMUSocket.class
/usr/share/i2p/lib/sam.jar:
/usr/share/i2p/lib/standard.jar:
/usr/share/i2p/lib/streaming.jar:
/usr/share/i2p/lib/systray.jar:
您...可能不想手动执行此操作。