2013-02-11 16 views
9

Próbowałem przez jakiś czas i wierzę, że jestem dość blisko tego, ale jestem całkiem nowy dla Uniksa, więc znajdowałem to trudne.Znajdź wszystkie zamki i rozpakuj w miejscu - Unix

Mam folder zawierający wiele folderów, z których niektóre zawierają pliki zip, a niektóre nie. Próbuję rozpakować wszystkie pliki zip w dowolnym podkatalogu w miejscu.

Przykładowo mam:

plików/A/something.java

plików/B/somezipfile.zip

plików/C/someotherfile.zip

plików/D/AnotherZipFile.zip

Chciałbym je rozpakować (zakładając, że zip zawiera tylko pliki .java), aby uzyskać wynik taki jak: files/A/something.ja va

pliki/B/javafile.java

pliki/C/someotherfilefromzip.java

plików/D/Anotherfile.java

Nie przeszkadza mi, jeśli pliki ZIP pozostają lub są usunięte po rozpakowaniu, albo jest w porządku.

Co próbowałem do tej pory.

1) Spodziewałem mogę użyć rur, który Jestem nowy, tak:

find . -name *.zip | unzip 

to nie działa.

2) Spędziłem trochę czasu na poszukiwanie, najbliższy mam stosując roztwór Online jest:

find . -name '*.zip' -exec unzip '{}' ';' 

rozpina to, ale rozpina je do bieżącego katalogu roboczego, chciałem je rozpakować w miejscu. Ja również nie rozumiem tego polecenia, które chciałbym, jak próbuję się nauczyć.

Każda pomoc jest doceniana.

Dzięki,

Odpowiedz

26
find . -name '*.zip' -exec sh -c 'unzip -d `dirname {}` {}' ';' 

poleceń wygląda to w bieżącym katalogu i jego podkatalogów w rekursywnie dla plików o nazwach odpowiadających *.zip wzorca. Dla znaleziono pliku to wykonuje polecenie sh z dwoma parametrami:

-c 

i

unzip -d `dirname <filename>` <filename> 

Gdzie <filename> jest nazwa pliku, który został znaleziony. Polecenie sh to interpreter powłoki Uniksa. Opcja -c mówi powłoce, że następny argument powinien być interpretowany jako skrypt powłoki.Więc powłoka zinterpretuje następujący skrypt:

unzip -d `dirname <filename>` <filename> 

Przed uruchomieniem unzip skorupę rozszerza polecenia, wykonując różne podstawienia. W tym konkretnym przykładzie zastępuje

`dirname <filename>` 

z wyjściem polecenia dirname <filename> które faktycznie wyprowadza nazwę katalogu, w którym plik jest umieszczony. Tak więc, jeśli nazwa pliku jest ./a/b/c/d.zip, powłoka będzie pocierać unzip tak:

unzip -d ./a/b/c ./a/b/c/d.zip 

W przypadku ZIP nazw plików lub nazwy katalogów mają spacje, użyj tego:

find . -name '*.zip' -exec sh -c 'unzip -d "`dirname \"{}\"`" "{}"' ';' 
+0

To wygląda na dobrą odpowiedź, czy możesz (bardzo szybko) pomóc mi ją zrozumieć? Trochę jestem zdezorientowany na temat potrzeby -exec i {} znaków. – ThePerson

+1

Dodane wyjaśnienie –

+0

Mam problem, jeśli w nazwie pliku zip znajduje się spacja, czy istnieje łatwa do rozwiązania? – ThePerson

7
find . -name '*.zip' | xargs -n1 unzip 
19

Korzystając -execdir zamiast z -exec, która uruchamia polecenie w katalogu, w którym znajduje się plik, a nie w katalogu, w którym działa find.

find . -name '*.zip' -execdir unzip '{}' ';' 
+0

Pracował fantastycznie. Czy możesz wyjaśnić, co robi '{{} (nazwa pliku zastępczego?) I dlaczego' ';' 'musi być oddzielną kwotą? Dzięki! –

+0

{} oznacza bieżący plik, na którym pracujesz – Tebe