2010-04-25 13 views
6

Widziałem pętle do rozpakowania wszystkich plików zip w katalogu. Jednak zanim to uruchomić, wolałbym się upewnić co mam biec będzie działać po prawej:Czy pętla powłoki rozpakuje wszystkie pliki w katalogu?

for i in dir; do cd $i; unzip '*.zip'; rm -rf *.zip; cd ..; done 

Zasadniczo chcę patrzeć na wyjściu „dir” zobacz wszystkie foldery dla każdego w katalogu cd, rozpakuj wszystkie archiwa zip, a następnie usuń je, a następnie odtwórz z powrotem i zrób to ponownie, dopóki ich nie będzie.

Czy jest to coś, co powinienem zrobić w jednym poleceniu, czy też powinienem rozważyć zrobienie tego w Perlu?

+1

Witam i zapraszam do StackOverflow. Aby kod był bardziej czytelny, użyj kodu-tagu –

+1

, aby uzyskać informacje, możesz użyć cd - aby powrócić do poprzedniego katalogu. – Aif

+0

@Patrick done :) – DVK

Odpowiedz

1

częściowo badane:

find . -type d -exec sh -c "cd \"{}\" ; unzip \"*.zip\" ; rm \"*.zip\" " \; 

uruchamia łańcuch cd/unzip/rm każdego podkatalogu.

+0

Na razie to działa, gdzie druga odpowiedź nie mogła wziąć rzeczy takich jak "Nazwa folderu ze spacją", jednak nie usuwa archiwów .zip. – helpwithshell

+0

Myślę, że musisz użyć 'find ... | xargs -0 ... 'do obsługi białych znaków, czy cytaty z cudzysłowem wykonują zadanie? – Anycorn

+0

W końcu udało mi się zmodyfikować linię poleceń do: znaleźć. -name "* .zip" -exec sh -c "rm -rf \" {} \ "" \; , aby usunąć wszystkie pozostawione archiwum .zip. dzięki – helpwithshell

1

Zastosowanie * aby uzyskać zawartość bieżącego katalogu:

for i in *; do cd "$i"; ...etc... ; done 

Należy również upewnić się, że coś jest katalogiem przed próbą cd do niego. W bash odbywa się to w sposób następujący:

if [ -d "$i" ]; then ...etc... ; fi 

Należy również być ostrożnym, aby sprawdzić, czy operacja rozpakowania udało przed usunięciem pliku zip. Nie ma potrzeby używania rekurencyjnego force delete do usuwania pojedynczego pliku.

Myślę, że to przesuwa granicę tego, co rozsądne, aby zrobić jedną linię. Umieść go w skrypcie powłoki i sformatuj go na wielu liniach.

2

Powinieneś mieć się dobrze w ogóle. W przypadku debugowania przedrostek wszystkich poleceń w pętli z echo powie ci, jak zmienne się rozwijają. Możesz też zawsze użyć pytania rm -i, aby otrzymać pytanie, zamiast robić rm dalej z czymkolwiek z -f.

Pojedyncze cytaty w Twoim zgłoszeniu unzip rozpakują tylko pliki o nazwie *.zip, tzn. * nie zostaną rozwinięte. Zamiast tego użyj podwójnych cudzysłowów (lub w ogóle bez cudzysłowów).

Twoja pętla przyjmuje teraz, że wszystkie katalogi $i znajdują się bezpośrednio pod bieżącym. Bardziej ogólnym rozwiązaniem byłoby użycie stosu katalogów (pushd i popd);

for i in $dir; do 
    pushd $i 
    unzip *.zip 
    rm -rf *.zip 
    popd 
done 
+0

Musiałem zmienić pierwszy z dla mnie w dir na dla mnie w *, to rozpakował rzeczy, jednak miał problemy z plikami, które zawierały spacje w nazwie. – helpwithshell

+0

@help: Domyślnie założyłem, że 'dir' był zmienną, kiedy nie było, więc mój przykład był błędny. Naprawiono tu i teraz zakłada, że ​​'dir' jest zmienną trzymającą listę katalogów. –

2

Kilka punktów dodając do tego, co mówili inni:

  • Jeśli umieścisz parametr w pojedynczych cudzysłowach, jak w '*.zip', powłoka nie zrobi karta rozszerzająca dziką i rozpakować postara się przetworzyć archiwum to jest dosłownie nazywane *.zip
  • Nie używaj -r jako parametru do rm, jeśli chcesz tylko usunąć pojedyncze pliki. Jest to niepotrzebnie niebezpieczne, ponieważ prawdopodobnie żadne rekursywne usuwanie podkatalogów nie byłoby zamierzone.
  • Należy sprawdzić kod powrotu unzip i tylko usunąć plik zip jeśli rozpakować powiodła się (na przykład można powiedzieć if unzip *.zip; then rm *.zip; fi lub nawet użyć wyraźny for pętlę przetwarzać pliki zip po jednej)
0

Gdy chcesz wiedzieć, czy coś będzie działać, ale obawiają się, że to destrukcyjne konsekwencje, zrobić trochę w czasie:

Sprawdź, czy masz odpowiednie pliki:

for i in dir; do cd $i; echo $i; cd ..; done 

Upewnij można rozpakować pliki przed usunięciem plików:

for i in dir; do cd $i; unzip '*.zip'; cd ..; done 

A, zanim zrobisz Goło i wesoło, zrobić kopię zapasową katalogu.

Powiązane problemy