Czy istnieje sposób na spakowanie wszystkich plików w danym katalogu za pomocą polecenia zip? Słyszałem o używaniu *.*, ale chcę, aby działało też z plikami bez rozszerzeń.

Komentarze

  • Czy próbowałeś przejść jeden poziom wyżej z wybranego katalogu i wykonać zip myarch.zip mydir/*?
  • lub lepiej zip -r myarch.zip mydir/*
  • lub lepiej zip -r myarch.zip mydir
  • *.* oznacza dowolny plik z kropką. W cp / m i dos, wszystkie pliki miały kropkę i spowodowało to konieczność jej wpisania (nie można było tego zrobić *). Dlatego ludzie przyszli zobaczyć *.* jako wszystkie pliki. Ostatecznie Microsoft dodał długie nazwy plików, które mogły mieć zero lub więcej kropek. Aby znaleźć plik, który ma kropkę w oknach, musisz wpisać *.*.*.

Odpowiedź

Możesz po prostu użyć *; nie ma potrzeby dla *.*. Rozszerzenia plików nie są specjalne w systemie Unix. * dopasowuje zero lub więcej znaków znaki – w tym kropka. Więc pasuje do foo.png, ponieważ to „zero lub więcej znaków (dokładnie siedem).

Zwróć uwagę, że * domyślnie nie „t dopasowuje plików zaczynających się kropką (podobnie *.*). Często tego chcesz. Jeśli nie, w bash, jeśli shopt -s dotglob będzie to (ale nadal będzie wykluczone . i ..). Inne powłoki mają różne sposoby dołączania plików dotfile (lub nie mają ich wcale).

Alternatywnie zip ma również -r (rekurencyjna) opcja wykonywania całych drzew katalogów naraz (bez martwienia się o problem z plikami dotfile):

zip -r myfiles.zip mydir 

gdzie mydir to katalog zawierający twoje pliki. Zwróć uwagę, że utworzony plik ZIP będzie zawierał strukturę katalogów, a także pliki. Jak zauważył peterph w swoim komentarzu, jest to zwykle postrzegane jako dobra rzecz: wypakowanie pliku zip będzie starannie przechowywać wszystkie rozpakowane pliki w jednym podkatalogu.

Możesz również nakazać zipowi, aby nie zapisywał ścieżek z Opcja -j / --junk-paths.

Polecenie zip zawiera dokumentacja informująca o wszystkich jego (wielu) opcjach; wpisz man zip, aby zobaczyć tę dokumentację. To nie jest unikalne dla zip; w ten sposób możesz uzyskać dokumentację dla większości poleceń.

Komentarze

  • Możesz dodać, że jest to za dobrą praktykę uważa się umieszczanie wszystkiego w archiwum w katalogu najwyższego poziomu – aby nie ' nie zanieczyszczać swojego bieżącego katalogu podczas rozpakowywania.
  • @peterph gotowe. Chociaż jest to mniej konwencja w plikach zip niż np. w plikach tar, ' boję się.
  • niestety tak. Prawdopodobnie z powodu okien dziedzictwo przeciągania ' n ' upuszczania na pulpit i linuxowe dziedzictwo pracy z kodami źródłowymi.
  • Zachowaj pamiętaj, że * shell-globbing nie ' nie zawiera plików z kropkami (tj. nazw plików zaczynających się od .). Jest to kolejna zaleta spakowania całego katalogu według nazwy.
  • Jednak użycie -r obejmuje sam katalog, co niszczy to, co ja ' robię. Czy nie ' t * obejmowałby . i ..?

Odpowiedź

W moim przypadku chciałem spakować każdy plik do jego własnego archiwum, więc zrobiłem co następuje (w zsh):

$ for file in *; do zip ${file%.*}.zip $file; done 

Komentarze

  • Tam ' nie mkv tutaj? Również nic tutaj nie jest szczególnie zsh -specyficzne. ' Będziesz chciał poprawnie cytować każdą zmienną zawierającą nazwę pliku, więc zip "${file%.*}.zip" "$file" z podwójnymi cudzysłowami wokół obu zmiennych.
  • @tripleee Po pierwsze, dziękuję za wskazanie mojego błędnego odniesienia do mkv. Po drugie, cytowanie argumentów jest niepotrzebne w zsh, w przeciwieństwie do bash. Właśnie dlatego ' wskazałem, że jest to polecenie dla zsh.
  • Zastąpienie ostatniego średnika znakiem znak ampersand może go znacznie przyspieszyć (jeśli liczba plików w katalogu jest rozsądna …). W przeciwnym razie find . -type f -maxdepth 1 -print0|xargs -r0 -n1 -P64 -I{} bash -c 'f="{}"; zip "${f%.*}.zip" "$f"' (z -P dostosowanymi w zależności od wątków procesora …) (Wiele zależności GNU …)
  • aby spakować każdy plik do własnego archiwum, wykonaj gzip *

Odpowiedz

Innym sposobem byłoby użycie funkcji find i xargs: (może to zawierać katalog „.” w pliku zip, ale nadal powinien zostać wyodrębniony poprawnie. W moim teście zip usunął kropkę przed kompresja) find . -type f -exec zip zipfile.zip {} +

(+ można zastąpić \; jeśli Twoja wersja find nie obsługuje zakończenia + dla exec. Będzie jednak wolniejsze …)

Domyślnie obejmie to wszystkie podkatalogi. W GNU find -maxdepth może temu zapobiec.

Komentarze

  • (w przeciwieństwie do rozwiązań używających *, obejmie to pliki dotfiles i nie spowoduje ' przewrócenia, jeśli w katalogu jest za dużo plików)

Odpowiedź

Inna (wolna) metoda, aby to zrobić (która dodaje po jednym pliku do ZIP):

for f in * .[^.]*; do [ -r "$f" ] || continue # Skip directories or non-existant files (Probably ".[^.]*" if directory has no dotfiles). Using -e will allow directories to be used as well zip zipfile.zip "$f" # If directories are included, you probably want to add -r done 

To ma problemy z dotfile * (obejście zostało dodane) i zostanie uruchomione spakowanie raz dla każdego pliku, dodając go do archiwum. W bash zajmowałoby się dużą ilością plików.

Byłoby wolniejsze niż większość innych metod, ale jest stosunkowo proste.

Komentarze

  • Powiedziałbym, że jest to mniej proste niż zaakceptowana odpowiedź i wolniejsze, co prowadzi do pytania: ” Dlaczego ktoś miałby to zrobić? „. Jeśli możesz odpowiedzieć na to pytanie, radzę umieścić ten kontekst w swojej odpowiedzi, w przeciwnym razie uważam, że jest to zła odpowiedź na stare pytanie, na które już jest dobra odpowiedź.
  • @Centimane: Zwracam uwagę na ograniczenia . Czuję, że ma to wartość edukacyjną. (Jeśli nie pomijasz katalogów, jest to dość proste). Jeśli chcesz uzyskać znacznie szybszą odpowiedź za pomocą (standardowego) narzędzia zewnętrznego, moja druga odpowiedź obejmuje to. (po usunięciu obsługi plików dotfiles (co wpływa na poprawność bez ich braku wspomnianego w pytaniu), wydaje mi się, że jest to całkiem eleganckie): for f in *; do zip zip.zip "$f"; done
  • Zauważ, że zaakceptowane odpowiedź nie ' nie używa zewnętrznego polecenia i działałaby szybciej. W jakim scenariuszu ta odpowiedź byłaby przydatna?
  • @Centimane Z tar, gdy jest więcej plików niż to, co bash może przekazać jako parametry. (znajdź + xargs są lepsze, bo pętle są łatwiejsze …). To (wyjątkowa) odpowiedź na to pytanie. Z pewnością nie jest to optymalna odpowiedź. (Nieoptymalne odpowiedzi mogą nadal być przydatne w przypadku podobnych problemów, jeśli ktoś ma nieco inną sytuację – np. Chcąc plik tar z jakimikolwiek katalogami)

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *