標準出力で解凍または同様のプログラムを動作させることはできますか?状況は、その場で解凍されるはずのzipファイルをダウンロードしていることです。
標準出力で解凍または同様のプログラムを動作させることはできますか?状況は、その場で解凍されるはずのzipファイルをダウンロードしていることです。
回答:
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)
このスクリプトは、1行に縮小してエイリアスとして作成できます。
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の両方のジョブを1つにロールアップします。ただし、zipに単一のファイルがある場合は、unzip -pを使用してファイルを標準出力に抽出できます。複数のファイルがある場合、ファイルの開始場所と停止場所を伝える方法はありません。
stdinからの読み取りについては、unzipのマニュアルページに次の文があります。
funzipを除いて、標準入力から読み取られたアーカイブはまだサポートされていません(アーカイブの最初のメンバーのみを抽出できます)。
funzipを使用すると幸運になるかもしれません。
あなたがしたいのは、unzip
引数としてではなく標準入力でZIP形式のファイルを取ることです。これは通常、容易でサポートされているgzip
とtar
の種類とツールの-
引数。しかし、標準unzip
はそれを行いません(ただし、パイプへの抽出はサポートしています)。しかし、すべてが失われるわけではありません...
見てくださいfunzipマニュアルページ。
ファイル引数のないfunzipはフィルターとして機能します。つまり、ZIPアーカイブ(またはgzipで圧縮されたファイル)が標準入力にパイプされていると想定し、アーカイブから最初のメンバーを標準出力に抽出します。stdinがttyデバイスからのものである場合、funzipはこれが(バイナリ)圧縮データのストリームではないことを想定し、代わりに短いヘルプテキストを表示します。ファイル引数がある場合、入力はstdinではなく指定されたファイルから読み取られます。
単一メンバーの抽出の制限を考えると、funzipはtar(1)などのセカンダリアーカイバプログラムと組み合わせて使用すると最も便利です。次のセクションには、テープへのディスクバックアップの場合のこの使用法を示す例が含まれています。
これは、ほとんどのLinuxアーカイブは通常TARで圧縮されてから、何らかの方法(gzip、bzipなど)でZIP圧縮されるという考えによく合います。があれば、これはあなたのために動作しますtar.ZIP
。
funzip
Info-ZIPの原作者であるMark Adlerによって書かれていることは注目に値します。彼はfunzipのmanページに書いています、
this functionality should be incorporated into unzip itself (future release).
ただし、そのような更新は見られません。他のアーカイブ方法はTARで簡単に機能したため、Markはそれを不要であると判断したと思われます。
curlはデフォルトでインストールされるため、curlを使用するのが好きです(-L
リダイレクトは頻繁に発生します)。
curl -L http://example.com/file.zip | bsdtar -xvf - -C /path/to/directory/
ただし、bsdtar
はデフォルトでインストールされていないためfunzip
、作業を開始できませんでした。
これは、同様の質問に対する私の答えの再投稿です。
ZIPファイル形式には、アーカイブの最後にディレクトリ(インデックス)が含まれます。このディレクトリは、アーカイブ内の各ファイルの場所を示しているため、アーカイブ全体を読み取ることなく、迅速でランダムなアクセスが可能です。
これは、パイプを介してZIPアーカイブを読み取ろうとするときに問題を引き起こすように見えます。インデックスは最後までアクセスされないため、ファイルが完全に読み取られて使用できなくなるまで個々のメンバーを正しく抽出できません。 。そのため、アーカイブがパイプを介して提供される場合、ほとんどのZIP解凍プログラムが単純に失敗するのは当然のことです。
アーカイブの最後のディレクトリは、ファイルメタ情報がアーカイブに保存される唯一の場所ではありません。さらに、冗長性のために、個々のエントリのローカルファイルヘッダーにもこの情報が含まれています。
インデックスが利用できない場合ではない、すべてのZIP解凍器は、ローカル・ファイル・ヘッダーを使用しますが、(bsdtarとbsdcpio別名)作者libarchiveにtarとcpioのフロントエンドは、となりますことができ、パイプを通して読んで次のことが可能であることを意味するときに行います。
wget -qO- http://example.org/file.zip | bsdtar -xvf-
zshでは、次のことができます。
unzip =( curl http://example.com/someZipFile.zip )
私の答えの再投稿:
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を使用している場合(Alpineなど)、単に実行し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ファイルです。