Unix에서 zip 파일 내부를 검색할 수 있습니까?

Unix에서 zip 파일 내부를 검색할 수 있습니까?

일부 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 한정자는 eglob의 출력을 수정하는 데 사용됩니다. 각 일치 항목에는 …/*.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줄 쉘 함수로 하드코딩합니다(그게 더 나쁘다). 이것다음 최고 평점 답변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훌륭한 ~/.zshrczip 파일 영광이 당신의 것이 될 것입니다 .set -e

예를 들어, 아니면 그런 일이 일어나지 않았어

설명하기 위해 다음에 포함된 모든 클래스 집합을 찾아보겠습니다.I2PGentoo Linux에 설치된 JAR 파일 이름은 7개의 대문자로 시작하고 그 뒤에 1개의 소문자가 옵니다.단지 때문에:

$ 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:

당신은 아마도 이 작업을 수동으로 수행하고 싶지 않을 것입니다.

관련 정보