developer tip

Unix 명령 줄에서 디렉토리 및 하위 디렉토리의 아카이브를 반복적으로 압축 해제하는 방법은 무엇입니까?

copycodes 2020. 12. 14. 20:04
반응형

Unix 명령 줄에서 디렉토리 및 하위 디렉토리의 아카이브를 반복적으로 압축 해제하는 방법은 무엇입니까?


unzip명령에는 아카이브를 반복적으로 압축 해제하는 옵션이 없습니다.

다음 디렉토리 구조 및 아카이브가있는 경우 :

/Mother/Loving.zip
/ 괴혈병 / Sea Dogs.zip
/Scurvy/Cures/Limes.zip

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

/Mother/Loving/1.txt
/Mother/Loving.zip
/ Scurvy / Sea Dogs / 2.txt
/ 괴혈병 / 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 {} \;

If you're using cygwin, the syntax is slightly different for the basename command.

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

I realise this is very old, but it was among the first hits on Google when I was looking for a solution to something similar, so I'll post what I did here. My scenario is slightly different as I basically just wanted to fully explode a jar, along with all jars contained within it, so I wrote the following bash functions:

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"
}

Note the <file-where-this-function-is-stored> which is needed if you're storing this in a file that is not read for a non-interactive shell as I happened to be. If you're storing the functions in a file loaded on non-interactive shells (e.g., .bashrc I believe) you can drop the whole source statement. Hopefully this will help someone.

A little warning - explodeFile also deletes the ziped file, you can of course change that by commenting out the last line.


Another interesting solution would be:

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;

참고URL : https://stackoverflow.com/questions/107995/how-do-you-recursively-unzip-archives-in-a-directory-and-its-subdirectories-from

반응형