Dekompresowanie wielu plików jednocześnie


27

Mam ponad 200 .zipplików w jednym folderze. Nie chcę dekompresować tych jeden po drugim. Chcę wyodrębnić te przy użyciu pojedynczego polecenia lub skryptu. Jak to zrobić.

Odpowiedzi:


38

Jeśli naprawdę chcesz je rozpakować równolegle, możesz to zrobić

for i in *zip; do unzip "$i" & done

To jednak uruchomi N procesów dla plików .zip i może być bardzo ciężkie dla twojego systemu. Aby uzyskać bardziej kontrolowane podejście, uruchamiając jednocześnie tylko 10 równoległych procesów, wypróbuj to:

find . -name '*.zip' -print0 | xargs -0 -I {} -P 10 unzip {}

Aby kontrolować liczbę uruchomionych równoległych procesów, zmień -Pna cokolwiek chcesz. Jeśli nie chcesz, aby rekursje następowały w podkatalogach, zrób to zamiast tego:

find . -maxdepth 1 -name '*.zip' -print0 | xargs -0 -I {} -P 10 unzip {}

Alternatywnie możesz zainstalować GNU równolegle, jak sugeruje @OleTange w komentarzach i uruchomić

parallel unzip ::: *zip

3
Równoległe działanie to dobry pomysł, ale czy dyskowe operacje we / wy nie będą głównym wąskim gardłem?
— Paddy Landau

1
@PaddyLandau nie jestem pewien, musiałbym to sprawdzić. Będzie to zależeć od szybkości algorytmu dekompresyjnego w zależności od prędkości dysku, jaki sobie wyobrażam.
— terdon

Użyj -execlub -execdirzamiast rurowania do xargs. Jest nie tylko łatwiejszy do zrozumienia, ale także mniej podatny na błędy i zużywa mniej zasobów systemowych. find . -name '*.zip' -exec unzip {} ';'(Musisz zacytować średnik).
— Paddy Landau

@PaddyLandau jedynym powodem, dla którego przesyłam strumieniowo do xargs, jest równoległe uruchamianie rzeczy, tak jak poprosił OP. -exec \;(możesz wstawić średnik, bez cudzysłowu), uruchomi każde polecenie sekwencyjnie. -exec +jest lepsze, ale tutaj nie będzie działać, ponieważ nie tak to unzipdziała.
— terdon

Myślę, że różnie rozumieliśmy PO. Czytasz go tak, jakby chciał tego równolegle, podczas gdy ja rozumiałem, że oznacza jedno polecenie zamiast wielu poleceń. Cóż, teraz ma obie metody :)
— Paddy Landau

17

Polecenie równoległe GNU jest dobrze dostosowane do tego typu rzeczy. Po:

$ sudo apt-get install parallel

Następnie

ls *.zip | parallel unzip

Spowoduje to użycie tyle rdzeni, ile masz, utrzymując każdy rdzeń zajęty rozpakowaniem, dopóki wszystkie nie zostaną zakończone.


Lepiej jest użyć echo *.zipzamiast tego, aby zapobiec wykradaniu się aliasu ls w dodatkowych informacjach. Jednak ma to ten sam problem, co odpowiedź @ Guru, psuje nazwy plików zawierające białe znaki.
— nyuszika7h

1
@ nyuszika7h W przeciwieństwie do xargsGNU Parallel nie łamie nazw plików zawierających spację / tab / cytat. Tylko jeśli nazwy plików zawierają nowe linie, będziesz musiał zachować szczególną ostrożność. Na przykład, używając:parallel unzip ::: *.zip
— Ole Tange

@ nyuszika7h - Są to dobre powody, aby unikać zarówno aliasingu standardowych poleceń, jak i wstawiania spacji w nazwach plików.
— Wayne Conrad

@ nyuszika7h używanie echojest tak samo złe, jak używanie ls. Globbing i pętla while są najbezpieczniejsze.
— terdon

1
@NateEldredge Podczas gdy ta szansa była większa w czasach, gdy systemy miały tylko jeden dysk magnetyczny, obecnie w przypadku macierzy RAID z wieloma wrzecionami i dyskiem flash ta szansa jest mniejsza. Najlepiej jest oczywiście zmierzyć i zobaczyć, jak zachowuje się twój system. Niedawno użyłem macierzy RAID o 40 wrzecionach, w których optymalna równoległość dla procesów głodnych we / wy wynosiła 10: Nie dawała 10-krotnego przyspieszenia - tylko 6-krotnie, ale mniej niż 10 procesów dało mniej niż 6-krotnie.
— Ole Tange

12

Możesz użyć następującego polecenia:

Najpierw zmień katalog w terminalu na katalog zawierający pliki .zip:

cd /path

Następnie uruchom to polecenie, aby rozpakować wszystkie pliki .zip:

for z in *.zip; do unzip "$z"; done

10

Jeśli masz wiele .zipplików w folderze i chcesz je zdekompresować, otwórz terminal i przejdź do folderu, używając:

cd <path_to_folder>

Teraz użyj tego polecenia, aby zdekompresować cały .zipplik:

ls *.zip | xargs -n1 unzip

3
Nie powiedzie się, jeśli którakolwiek z nazw plików zawiera spacje.
— terdon

1
tak, masz rację.
— g_p

Lepiej jest użyć echo *.zipzamiast tego, aby zapobiec lswykradaniu się aliasu w dodatkowych informacjach, jednak to nadal nie rozwiązuje problemu białych znaków.
— nyuszika7h

1
@OleTange W przypadku, gdy nie zauważyłeś, powiedziałem, że nadal nie działa na nazwach plików z białymi spacjami.
— nyuszika7h

1
Nigdy nie zależą od danych wyjściowych lsskryptów, ponieważ dane wyjściowe nie są dobrze zdefiniowane między wersjami. Zamiast tego spójrz na odpowiedź @terdon, która rozwiązuje wszystkie problemy tego rozwiązania.
— Paddy Landau

6

Możesz użyć find z -execpodobnym,

find . -name "*.zip" -exec unzip {} \;

Działa to, jeśli plik ma spację w nazwie.


3

Nieterminowa metoda.

Po prostu wybierz pliki zip, kliknij jeden z nich prawym przyciskiem myszy i wybierz extract here. Możesz wybrać wszystkie lub tylko kilka plików zip na raz.


1

unzip \*.zip lub unzip '*.zip'

Oczywiste unzip *.zipnie działa, ponieważ powłoka rozwija go unzip foo.zip bar.zip ...i unzipinterpretuje pierwszą nazwę pliku jako plik zip, a kolejne nazwy plików jako pliki do wyodrębnienia z tego pliku zip.

Jednak unzipjest nieco nietypowe wśród poleceń Unix, że robi swoje ekspansje glob. Jeśli *powłoka nie zostanie rozwinięta przez powłokę, rozpakuje ją i zinterpretuje wszystkie wynikowe nazwy plików jako pliki zip do przetworzenia. Więc w tym szczególnym przypadku można uciec bez forpętli xargslub tym podobnych.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.