Unix 명령줄에서 디렉터리와 해당 하위 디렉터리의 아카이브를 어떻게 반복적으로 압축 해제합니까?

StackOverflow https://stackoverflow.com/questions/107995

  •  01-07-2019
  •  | 
  •  

문제

그만큼 unzip 명령에는 아카이브의 압축을 반복적으로 풀기 위한 옵션이 없습니다.

다음과 같은 디렉토리 구조와 아카이브가 있는 경우:

/Mother/Loving.zip
/Scurvy/Sea Dogs.zip
/Scurvy/Cures/Limes.zip

그리고 모든 아카이브를 각 아카이브와 동일한 이름을 가진 디렉터리에 압축을 풀고 싶습니다.

/Mother/Loving/1.txt
/Mother/Loving.zip
/Scurvy/Sea Dogs/2.txt
/Scurvy/Sea Dogs.zip
/Scurvy/Cures/Limes/3.txt
/Scurvy/Cures/Limes.zip

어떤 명령을 실행해야 합니까?

공백이 있는 파일 이름으로 인해 문제가 발생하지 않는 것이 중요합니다.

도움이 되었습니까?

해결책

해당 폴더에 파일을 추출하려면 다음을 시도해 보십시오.

find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done;

높은 I/O를 처리할 수 있는 시스템을 위한 다중 처리 버전:

find . -name "*.zip" | xargs -P 5 -I fileName sh -c 'unzip -o -d "$(dirname "fileName")/$(basename -s .zip "fileName")" "fileName"'

다른 팁

다음은 find 명령과 while 루프를 포함하는 한 가지 솔루션입니다.

find . -name "*.zip" | while read filename; do unzip -o -d "`basename -s .zip "$filename"`" "$filename"; done;

모든 파일 이름(줄 바꿈 포함)을 올바르게 처리하고 확장자를 제거한 채 파일과 동일한 위치에 있는 디렉터리로 추출하는 솔루션:

find . -name '*.zip' -exec sh -c 'unzip -o -d "${0%.*}" "$0"' '{}' ';'

더 많은 파일 형식(예: .jar) 다음을 사용하여 추가합니다. -o, 예:

find . '(' -name '*.zip' -o -name '*.jar' ')' -exec ...

단일 명령줄에서 -exec 플래그와 함께 find를 사용하여 작업을 수행할 수 있습니다.

find . -name "*.zip" -exec unzip {} \;

-r 플래그를 사용하는 gunzip과 같은 것?....

디렉터리 구조를 재귀적으로 이동합니다.명령줄에 지정된 파일 이름 중 하나라도 디렉터리인 경우 gzip은 해당 디렉터리로 내려와 거기서 찾은 모든 파일을 압축합니다(또는 gunzip의 경우 압축을 푼다).

http://www.computerhope.com/unix/gzip.htm

이는 우리가 원하는 대로 완벽하게 작동합니다.

파일 압축 해제:

find . -name "*.zip" | xargs -P 5 -I FILENAME sh -c 'unzip -o -d "$(dirname "FILENAME")" "FILENAME"'

위 명령은 중복 디렉토리를 생성하지 않습니다.

모든 zip 파일을 제거합니다.

find . -depth -name '*.zip' -exec rm {} \;

cygwin을 사용하는 경우 basename 명령의 구문이 약간 다릅니다.

find . -name "*.zip" | while read filename; do unzip -o -d "`basename "$filename" .zip`" "$filename"; done;

나는 이것이 매우 오래되었다는 것을 알고 있지만 비슷한 것에 대한 해결책을 찾고 있을 때 Google에서 첫 번째 히트작 중 하나였으므로 여기에 내가 한 일을 게시하겠습니다.기본적으로 항아리와 그 안에 포함된 모든 항아리를 완전히 폭발시키고 싶었기 때문에 내 시나리오는 약간 다릅니다. 그래서 다음 bash 함수를 작성했습니다.

function explode {
    local target="$1"
    echo "Exploding $target."
    if [ -f "$target" ] ; then
        explodeFile "$target"
    elif [ -d "$target" ] ; then
        while [ "$(find "$target" -type f -regextype posix-egrep -iregex ".*\.(zip|jar|ear|war|sar)")" != "" ] ; do
            find "$target" -type f -regextype posix-egrep -iregex ".*\.(zip|jar|ear|war|sar)" -exec bash -c 'source "<file-where-this-function-is-stored>" ; explode "{}"' \;
        done
    else
        echo "Could not find $target."
    fi
}

function explodeFile {
    local target="$1"
    echo "Exploding file $target."
    mv "$target" "$target.tmp"
    unzip -q "$target.tmp" -d "$target"
    rm "$target.tmp"
}

참고하세요 <file-where-this-function-is-stored> 이것은 내가 그랬던 것처럼 비대화형 쉘에 대해 읽혀지지 않는 파일에 이것을 저장하는 경우 필요합니다.비대화형 셸에 로드된 파일에 함수를 저장하는 경우(예: .bashrc 나는 믿는다) 전체를 버릴 수 있다 source 성명.이것이 누군가에게 도움이 되기를 바랍니다.

약간의 경고 - explodeFile 또한 압축된 파일을 삭제합니다. 물론 마지막 줄을 주석 처리하여 변경할 수 있습니다.

또 다른 흥미로운 해결책은 다음과 같습니다.

DESTINY=[Give the output that you intend]

# Don't forget to change from .ZIP to .zip.
# In my case the files were in .ZIP.
# The echo were for debug purpose.

find . -name "*.ZIP" | while read filename; do
ADDRESS=$filename
#echo "Address: $ADDRESS"
BASENAME=`basename $filename .ZIP`
#echo "Basename: $BASENAME"
unzip -d "$DESTINY$BASENAME" "$ADDRESS";
done;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top