Ekstrakcja plików .gz zawartych w folderze


13

Mam folder zawierający około 320116 plików .pdb.gz. Chcę je wszystkie zdekompresować. Jeśli użyję gunzip * .gz, pojawia się błąd, tzn. Lista argumentów jest za długa. Folder ma około 2 GB. Proszę o odpowiednią sugestię.


Jeśli będziesz musiał długo pracować nad tą strukturą katalogów, podziel ten katalog na wiele. Na przykład na podstawie czasu modyfikacji plików lub nazwy pliku.
— dan

Tak, muszę pracować długoterminowo. zostały wyodrębnione teraz Chcę podzielić i podzielić je na trzy foldery na podstawie ich nazw. Czy można to zrobić za pomocą skryptu powłoki?
— Lily Sharpton,

Sugeruję, abyś tam poszukał podobnych pytań. Jeśli nie znajdziesz takiego, który odpowiada Twoim potrzebom, zadaj nowe pytanie.
— dan

Odpowiedzi:


25
find . -name '*.pdb.gz' -exec gunzip {} +

-exec gunzip {} +zapewni gunzipwiele, ale nie za dużo nazw plików w wierszu poleceń. Jest to bardziej wydajne niż w przypadku, -exec gunzip {} \;gdy rozpoczyna się nowy gunzipproces dla każdego pliku.


3
Jeden find, mniej gunzip!
— dan

2
Zauważ, że „+” to GNUism i dlatego nie będzie działać na systemach innych niż GNU, takich jak * BSD.
— Przywróć Monikę - M. Schröder

3
Późniejsze wersje BSD findumożliwiają zapis „+”. Zobacz na przykład stronę podręcznika użytkownika finddla BSD 10.1 . Dotyczy to również OS X (10.9 i przynajmniej później, może wcześniej).
— plazma

7

Ilekroć pojawią się błędy „zbyt długiej listy argumentów”, możesz obejść ją, wielokrotnie wywołując żądane polecenie, za każdym razem z podzbiorem argumentów, których chcesz użyć. xargsto narzędzie, które pomaga to zrobić automatycznie.

find . -type f -a -name \*.pdb.gz -print0 | xargs -0 gunzip

czy to nie ma takiej samej nieefektywności jak -execdir gunzip "{}" \;np. że xargs wywoła gunzip osobno dla każdego pliku? To jest moje czytanie strony man.
— gogoud

5
Nie, xargsumieści tyle nazw plików, ile zmieści się w gunziplinii poleceń. Spróbuj! echo a b c d e f | xargs echowywołuje tylko echoraz ze wszystkimi 6 argumentami, więc widzisz jeden wiersz wyniku (chociaż całkiem bezużyteczne polecenie do wykonania !!!!), a jeśli wymusisz podanie xargstylko 3 argumentów na wywołanie polecenia za pomocą, echo a b c d e f | xargs -n 3 echowtedy otrzymasz 2 wiersze wyniku .
— Celada,

4
Kolejną zaletą używania xargsjest to, że z tą -Popcją możesz uruchamiać wiele gunzipprocesów równolegle, co (w zależności od dokładnych parametrów twojego systemu) może przebiegać szybciej.
— psmears

dzięki za wskaźnik do -P@psmears. Teraz też się czegoś nauczyłem!
— Celada,

1

Myślę, że to powinno działać, przekazuje ścieżkę / nazwę każdego pliku osobno do gunzip w celu przetworzenia:

find /my/dir -name "*.pdb.gz" -execdir gunzip "{}" \;

1
Spowoduje to uruchomienie gunzip raz na plik. Zobacz odpowiedź John1024 na nieco inny sposób, który pozwala uniknąć tej nieefektywności.
— Celada,

@Celada To było celowe; obawiałem się, że użycie + może ponownie prowadzić do komunikatu o błędzie z powodu przeciążenia gunzip. Jeśli metoda John1024 działa, jest technicznie bardziej wydajna, ale moja powinna działać, jeśli jego nie.
— gogoud

1
findz +i xargssą wyraźnie projektowane z myślą o tym właśnie problemie. Zawsze podają jak najwięcej argumentów, nie przekraczając limitu systemu operacyjnego. Bo, nawiasem mówiąc, jest to limit systemu operacyjnego, z którym nie ma nic wspólnego gunzip.
— Celada

1
@Celada ok, dziękuję za te informacje, więc przypuszczalnie z „+” gunzip można wywołać więcej niż jeden raz, ale mniej niż 320 000 razy?
— gogoud

1
poprawny.
— Celada,

1

Wypróbuj w ten sposób:

find . -name '*.gz' -exec gunzip {} \;

3
To będzie wykonywane gunzipraz na plik. Zobacz odpowiedź John1024 na nieco inny sposób, który pozwala uniknąć tej nieefektywności.
— Celada,

Pamiętaj, aby uciec z * w * .gz ...
— user253751

1

Jeśli masz maszynę wielordzeniową, prawdopodobnie zauważysz, że korzystanie z niej gunzipnie zmaksymalizuje możliwości twojego komputera. W tym celu musisz uruchomić wiele gunzips równolegle. Śledzenie, które operacje są wykonywane w tym, który terminal jest ręcznie, jest uciążliwe, ale możesz to łatwo zrobić z GNU równoległym:

find . -name "*.gz" | parallel -X gunzip {}

1
Czy to nie zawiedzie, ponieważ lista argumentów do paralleljest za długa?
— user253751,

@immibis Tak, zapomniałem o pierwotnym problemie, zaktualizuję swój post
— Anthon

Nie będzie to jednak nie dlatego, że lista jej argumentów na findto zbyt długo?
— user253751,

1
tak, ale podajesz wszystkie nazwy plików w findwierszu poleceń.
— user253751,

Wydaje się, że to nie jest dobry dzień na udzielanie odpowiedzi na pytania, zapomniałem zacytować argument-name
— Anthon

-1

Nie jest do findtego konieczne użycie , ponieważ nie wspomniano o podfolderach. Co musisz zrobić, to:

for f in *.gz;do gunzip $f;done

4
Ci nie muszą find, jeśli nie chcą tarło 320116 gunzipprocesów, tak jak to robi pętlę.
— John WH Smith,
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.