압축 해제 또는 유사한 프로그램을 표준 출력에서 작동시킬 수 있습니까? 상황은 압축 파일을 다운로드하는 중이며 압축이 풀린 상태입니다.
압축 해제 또는 유사한 프로그램을 표준 출력에서 작동시킬 수 있습니까? 상황은 압축 파일을 다운로드하는 중이며 압축이 풀린 상태입니다.
답변:
zip 파일은 실제로 컨테이너 형식이지만 파일이 메모리에 쉽게 들어갈 수있는 경우 파이프 (stdin)에서 읽을 수없는 이유는 없습니다. 다음은 zip 파일을 표준 입력으로 가져 와서 현재 디렉토리 또는 지정된 경우 지정된 디렉토리로 컨텐츠를 추출하는 Python 스크립트입니다.
import zipfile
import sys
import StringIO
data = StringIO.StringIO(sys.stdin.read())
z = zipfile.ZipFile(data)
dest = sys.argv[1] if len(sys.argv) == 2 else '.'
z.extractall(dest)
이 스크립트는 한 줄로 축소하여 별칭으로 만들 수 있습니다.
alias unzip-stdin="python -c \"import zipfile,sys,StringIO;zipfile.ZipFile(StringIO.StringIO(sys.stdin.read())).extractall(sys.argv[1] if len(sys.argv) == 2 else '.')\""
이제 wget의 출력을 쉽게 압축 해제하십시오.
wget http://your.domain.com/your/file.zip -O - | unzip-stdin target_dir
.read()
방법 을 사용하여 메모리의 전체 파일을 읽는 중입니다.
이것은 예상대로 작동하지 않을 것입니다. Zip은 압축 형식 일뿐만 아니라 컨테이너 형식이기도합니다. tar 및 gzip.bzip2 작업을 하나로 롤업합니다. zip에 단일 파일이 있으면 unzip -p를 사용하여 파일을 stdout으로 추출 할 수 있습니다. 파일이 둘 이상인 경우 파일의 시작 및 중지 위치를 알 수있는 방법이 없습니다.
stdin에서 읽을 때 unzip 매뉴얼 페이지에는 다음 문장이 있습니다.
funzip을 제외하고 표준 입력에서 읽은 아카이브는 아직 지원되지 않습니다 (그리고 아카이브의 첫 번째 멤버 만 추출 할 수 있음).
funzip으로 운이 좋을 수도 있습니다.
당신이하고 싶은 일은 unzip
인수가 아닌 표준 입력으로 ZIP 파일을 가져 오는 것입니다. 이것은 일반적으로 사용하여 쉽게 지원 gzip
및 tar
현물과 도구의 -
인수입니다. 그러나 표준 unzip
은 그렇게하지 않습니다 (물론 파이프로의 추출을 지원합니다). 그러나 모든 것이 손실되지는 않습니다 ...
봐 funzip 매뉴얼 페이지.
파일 인수가없는 funzip은 필터 역할을합니다. 즉, ZIP 아카이브 (또는 gzip 파일)가 표준 입력으로 파이프되고 있다고 가정하고 아카이브에서 stdout으로 첫 번째 멤버를 추출합니다. stdin이 tty 장치에서 오는 경우 funzip은이 데이터가 (이진) 압축 데이터 스트림 일 수 없다고 가정하고 대신 짧은 도움말 텍스트를 표시합니다. 파일 인수가 있으면 stdin 대신 지정된 파일에서 입력을 읽습니다.
단일 구성원 추출에 대한 제한을 감안할 때 funzip은 tar (1)와 같은 보조 아카이버 프로그램과 함께 사용하면 가장 유용합니다. 다음 섹션에는 테이프에 디스크 백업의 경우이 사용법을 보여주는 예가 포함되어 있습니다.
이것은 대부분의 리눅스 아카이브가 일반적으로 TAR되고 어떤 식 으로든 압축된다는 생각과 잘 어울립니다 (gzip, bzip 등). 당신이있는 경우에 당신을 위해 일할 것 tar.ZIP
입니다.
funzip
Info-ZIP의 원저자 인 Mark Adler가 작성한 것은 주목할 가치가 있습니다. 그는 funzip 맨 페이지에 글을 쓰고
this functionality should be incorporated into unzip itself (future release).
그러나 그러한 업데이트는 보이지 않습니다. 다른 보관 방법이 TAR에서 쉽게 작동했기 때문에 Mark가 필요하지 않다고 생각합니다.
이것은 비슷한 질문에 대한 나의 대답 을 다시 게시 한 것입니다 .
ZIP 파일 형식은 아카이브 끝에 디렉토리 (인덱스)를 포함합니다. 이 디렉토리는 아카이브 내에서 각 파일의 위치를 알려주므로 전체 아카이브를 읽지 않고도 신속하고 무작위로 액세스 할 수 있습니다.
이것은 파이프를 통해 ZIP 아카이브를 읽으려고 할 때 문제가있는 것으로 보입니다. 인덱스는 끝까지 액세스 할 수 없으므로 파일을 완전히 읽은 후 더 이상 사용할 수 없을 때까지 개별 멤버를 올바르게 추출 할 수 없습니다. . 따라서 아카이브를 파이프를 통해 공급할 때 대부분의 ZIP 압축 풀기 프로그램이 실패하는 것은 놀라운 일이 아닙니다.
아카이브의 끝에있는 디렉토리는 파일 메타 정보가 아카이브에 저장되는 유일한 위치 는 아닙니다 . 또한 개별 항목은 중복을 위해이 정보를 로컬 파일 헤더에 포함합니다.
모든 ZIP 압축 풀기 프로그램이 색인을 사용할 수 없을 때 로컬 파일 헤더를 사용하는 것은 아니지만 tar 및 cpio 프론트 엔드는 libarchive (일명 bsdtar 및 bsdcpio) 로 파이프를 읽을 때 수행 할 수 있으며 그렇게 할 것입니다 .
wget -qO- http://example.org/file.zip | bsdtar -xvf-
BusyBox unzip
는 stdin을 가지고 모든 파일을 추출 할 수 있습니다.
wget -qO- http://downloads.wordpress.org/plugin/akismet.2.5.3.zip | busybox unzip -
대시 unzip
는 stdin을 입력으로 사용하는 것입니다.
당신은 할 수 있습니다
cat file.zip | busybox unzip -
그러나 그것은 단지 중복입니다 unzip file.zip
.
배포판에서 기본적으로 BusyBox를 사용하는 경우 (예 : 알파인)을 실행하십시오 unzip -
.
실제로 좀 더 복잡한 것이 필요했습니다. 특정 파일이 있으면 추출하십시오. 어려움은 입력 파일 스트림이 zip 파일이 아니기 때문에 파이프를 계속 통과해야한다는 것입니다. 여기 내 솔루션이 있습니다 (주로 Jason R. Coombs 솔루션 덕분에)
python -c "import zipfile,sys,StringIO
data=sys.stdin.read()
try:
z=zipfile.ZipFile(StringIO.StringIO(data))
z.open(\"$1\")
sys.stdout.write(z.read(\"$1\"))
except (RuntimeError, zipfile.BadZipfile):
sys.stdout.write(data)"
이 파일을 내 컴퓨터의 "/ bin"폴더에 "effpoptp"(단순 이름 아님)이라는 파일로 저장 했으므로 테스트하는 방법은 다음과 같습니다.
cat defaultModel.mwb|effpoptp "document.mwb.xml"
목적은 MySQL Workbench 파일을 버전 제어하는 것입니다. 여기서 파일은 워크 벤치 파일로 이름 지정된 xml 파일 또는 전체 워크 벤치 파일 일 수 있습니다.