Unix 명령줄에서 디렉터리와 해당 하위 디렉터리의 아카이브를 어떻게 반복적으로 압축 해제합니까?
문제
그만큼 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의 경우 압축을 푼다).
이는 우리가 원하는 대로 완벽하게 작동합니다.
파일 압축 해제:
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;