Bir borudan geçen dosyaları açmak


39

Sıkıştırılmış veya benzer programların standart çıktıda çalışmasını sağlayabilir miyim? Durum şu anda anında açılmış olması gereken bir zip dosyası indiriyorum.

İlgili sorun: İndirilen bir dosyayı bash'taki standart çıktıya nasıl aktarırım?


Bu yapılabilir gibi görünüyordu, ancak zip yalnızca tek bir dosya içeriyorsa, yalnızca bir zip'i ayıklamak ve dosyayı başka bir komuta aktarmak mümkün gibi görünüyor. Çok dosyalı bir zipten belirli bir dosyayı çıkartmak istedim. Borular yerine, 'unzip file.zip / path / file && dostuff / path / file && rm -rf / path' komutlarını değiştirdim. Orijinal soruyu cevaplamadığımda ve geçici dosyaların yaratılmasıyla sonuçlandı. ihtiyaç.
Stan Kurdziel

Domuzu kontrol et. Bir boruda kullanıyoruz. andrew.tumblr.com/post/2316602611
dmourati

Yanıtlar:


22

Bir zip dosyası aslında bir kapsayıcı format olmasına rağmen, eğer dosya yeterince belleğe sığabiliyorsa, bir borudan (stdin) okunamamasının bir nedeni yoktur. Bir zip dosyasını standart girdi olarak alan ve içeriği geçerli dizine veya belirtilmişse belirtilen dizine çeken bir Python betiği.

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)

Bu komut dosyası bir satıra küçültülebilir ve takma ad olarak oluşturulabilir.

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 '.')\""

Şimdi wget çıktısını kolayca açın.

wget http://your.domain.com/your/file.zip -O - | unzip-stdin target_dir

1
Siz ve python rock !!!
Farid Nouri Neshat

3
Güzel bir liner ve +1, dosyanın belleğe sığması gerektiğini belirtti. (Maalesef, dosya formatı yapısı nedeniyle pkzip dosyasını açmanın bir yolu yoktur).
9x12'de lxgr

2
aklınızda bulundurun, bu ayıklamadan önce hafızada her şeyi tamponlar
William Casarin

1
Dosya yeterince belleğe yeterince sığabiliyorsa, akış olarak okunamıyor olmasının hiçbir nedeni yoktur . İçeriği çıkarmadan önce tüm zip arşivini bellekte tamponlamanızın nedeni, özellikle bir akış olarak okunamadığıdır. Elbette, zip arşivini bir dosyaya yazmaktan kaçınmak faydalı olabilir.
Håkan Lindqvist,

Bu bir akış değil , .read()yöntemi kullanarak hafızanın tamamını okuyorsunuz
Romuald Brunet

17

Beklediğiniz gibi çalışması mümkün değildir. Zip yalnızca bir sıkıştırma biçimi değil aynı zamanda bir kapsayıcı biçimidir. Hem tar hem de gzip.bzip2'nin işlerini bir araya getirir. Zip'inizin tek bir dosyası varsa, dosyaları stdout'a çıkarmak için unzip -p komutunu kullanabilirsiniz. Birden fazla dosyanız varsa, nerede başladığını ve durduğunu söylemenizin yolu yoktur.

Stdin'den okuma gelince, unzip man sayfasının şu cümleyi var:

Standart girdiden okunan arşivler funzip dışında henüz desteklenmiyor (ve yalnızca arşivin ilk üyesi çıkarılabilir).

Funzip ile biraz şansınız olabilir.


Unzip -p temp.zip dosya içi-zip: zip içindeki birden fazla dosya varsa, o zaman -p parametre olarak dosya adını kullanarak tek bir dosya yazdırabilirsiniz
Taavi Ilves'in

7

Yapmak istediğiniz, unzipargüman olarak değil, standart girişinde ZIPped bir dosya alın. Bu genellikle kolayca tarafından desteklenen gzipve tarnazik bir ile araçların -argüman. Ancak, standart unzipbunu yapmaz (yine de, bir borunun çıkarılmasını destekler). Ancak, hepsi kaybolmaz ...

Bak funzip manuel sayfa.

dosya argümanı olmadan funzip, filtre işlevi görür; yani, bir ZIP arşivinin (veya bir gzip'd dosyasının) standart girdiye aktarıldığını varsayar ve ilk üyeyi arşivden stdout'a çıkarır. Stdin bir tty cihazından geldiğinde, funzip, bunun (ikili) sıkıştırılmış veri akışı olamayacağını ve bunun yerine kısa bir yardım metni gösterdiğini varsayar. Bir dosya argümanı varsa, giriş, stdin yerine belirtilen dosyadan okunur.

Tek üyeli çıkarma işlemindeki sınırlamalar göz önüne alındığında, funzip en çok tar (1) gibi ikincil bir arşivleme programı ile birlikte kullanışlıdır. Aşağıdaki bölüm, teybe disk yedekleme durumunda bu kullanımı gösteren bir örnek içerir.

Bu, çoğu linux arşivinin genellikle TAR'ed olduğu ve daha sonra bir şekilde ZIPPed olduğu fikrine uyuyor (gzip, bzip, et al). Eğer varsa, bu sizin için çalışacaktır tar.ZIP.


funzipInfo-ZIP orijinal yazarı Mark Adler tarafından yazılmış olması dikkat çekicidir . Funzip man sayfasında yazıyor,

this functionality should be incorporated into unzip itself (future release).

ancak, böyle bir güncelleme görülmedi. Diğer arşivleme yöntemlerinin TAR ile kolayca çalıştığı için Mark'ın gereksiz bulduğundan şüpheleniyorum.


Sadece bir yorum; Bazı insanlar, açmak için bir seçenek olarak python veya herhangi bir dili ister. En önemli örnek, sisteminde katran veya fermuar içermeyen Heroku'dur. Etrafında bir çalışma izin verilen Java yükleyerek jar kullanmaktır.
Nick

Bu cevapta funzip ve benzeri araçların (özellikle de ilk arşiv üyesini gösterme kabiliyetine sahip) kısıtlamaları ile ilgilenmekle ilgili daha fazla şey var: unix.stackexchange.com/a/211286/77539
Joshua Goldberg

6

Curl kullanmayı severim çünkü varsayılan olarak yüklenir ( -Lgenellikle oluşan yönlendirmeler için gereklidir):

curl -L http://example.com/file.zip | bsdtar -xvf - -C /path/to/directory/

Ancak, bsdtarvarsayılan olarak yüklü değil funzipve çalışamadım.


Ayrıca birden fazla
dosyayla

5

Bu, benzer bir soruya verdiğim cevabın bir kopyası :

ZIP dosya formatı arşivin sonunda bir dizin (dizin) içerir. Bu dizin, arşiv içindeki her dosyanın nerede bulunduğunu ve böylece arşivin tamamını okumadan hızlı, rasgele erişime izin verdiğini söyler.

Bir borudan bir ZIP arşivi okumaya çalışırken, indekse sonuna kadar erişilemediğinden ve bireysel üyeler dosya tamamen okunana ve artık bulunamayana kadar doğru şekilde ayıklanamadığı için bir problem ortaya çıkıyor gibi görünmektedir. . Bu nedenle, çoğu ZIP dekompresörünün, arşiv bir borudan beslendiğinde kolayca başarısız olması şaşırtıcı değildir.

Arşivin sonundaki dizin, meta bilgilerinin arşivde depolandığı tek yer değil . Ek olarak, bireysel girişler bu bilgiyi fazlalık amacıyla yerel bir dosya başlığında da içerir.

Her ZIP sıkıştırıcısı, dizin kullanılamadığında yerel dosya başlıklarını kullanmasa da, katran ve cpio önü libarchive (aka bsdtar ve bsdcpio) bir borudan okurken bunu yapabilir ve yapacaktır :

wget -qO- http://example.org/file.zip | bsdtar -xvf-

4

En yaygın OSS uygulaması olan Info-Zip ile mümkün değildir. Daha da önemlisi, ZIP arşivlerinin yapıları nedeniyle tavsiye edilmez.

Biçim değişikliği sizin için geçerliyse, bunun yerine tar (1) kullanmayı düşünün. Akışlı girdi / çıktıdan oldukça memnun ve aslında varsayılan olarak bekliyor.

Ek olarak, bir dosya adı için "-" i belirleyerek uygulamaların akışlı girdi / çıktı beklemesini bekleyebilirsiniz. Info-Zip, tahmin edebileceğiniz gibi, bunu geçerli bir argüman olarak değerlendirmiyor.


4

Zsh'de aşağıdakileri yapabilirsiniz:

unzip =( curl http://example.com/someZipFile.zip )

3

Bunu yapacak en basit ortak yardımcı program jar, STDIN'in dosya argümanını geçmediğiniz takdirde kullanıldığını varsayar. Aynı zamanda tarişlemler için programa benzer argümanlar alır .

örneğin bir arşivin içeriğini listele

curl https://my.example.com/file.zip | jar t

Java her zaman yüklü olmasa da, jarolduğu makinelerde kesinlikle bunu yapmanın en uygun yöntemidir.


3

Cevabımın tekrarı :

BusyBox unzip, stdin'i alabilir ve tüm dosyaları çıkarabilir.

wget -qO- http://downloads.wordpress.org/plugin/akismet.2.5.3.zip | busybox unzip -

Sonrasındaki çizgi unzip, stdin'i giriş olarak kullanmaktır.

Yapabilirsin

cat file.zip | busybox unzip -

Ama bu sadece gereksiz unzip file.zip.

Dağıtımınız varsayılan olarak BusyBox kullanıyorsa (örn. Alpine), sadece çalıştırın unzip -.


1

Aslında biraz daha karmaşık bir şeye ihtiyacım vardı - eğer varsa belirli bir dosyayı çıkartın. Zorluk, girdi dosyası akışı bir zip dosyası olmayabilir ve bu durumda borudan geçmeye ihtiyacım vardı. İşte benim çözümüm (çoğunlukla Jason R. Coombs çözümü için teşekkürler)

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

Bunu, makinemdeki "/ bin" klasöründe "effpoptp" (basit bir ad değil) adlı bir dosya olarak kaydetmiştim.

cat defaultModel.mwb|effpoptp "document.mwb.xml"

Bunun amacı, dosyanın çalışma dosyası dosyası olarak adlandırılan xml dosyası veya tam çalışma dosyası dosyası olabileceği MySQL Workbench dosyalarını denetlemektir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.