Linux gzip wiele podkatalogów w osobne archiwa?

16

Jak mogę skompresować podkatalogi do osobnych archiwów?

Przykład:

directory
 subdir1
 subdir2

Powinien utworzyć podkatalog1 (.tar) .gz i podkatalog2 (.tar) .gz

EarthMind
źródło

Odpowiedzi:

27

Ten mały skrypt wydaje się najlepszą opcją, biorąc pod uwagę twoje wymagania:

cd directory
for dir in */
do
  base=$(basename "$dir")
  tar -czf "${base}.tar.gz" "$dir"
done

Prawidłowo obsługuje katalogi ze spacjami w ich nazwach.

Juliano
źródło
Daje mi ten błąd: bash: -c: wiersz 1: błąd składniowy: nieoczekiwany koniec pliku
EarthMind
@EarthMind: Tu działa dobrze. Sprawdź, czy skrypt został poprawnie skopiowany.
Juliano
@EarthMind: Nie jestem pewien, czy dobrze przeliterowałeś oryginalne pytanie. Chcesz uruchomić to ponownie i uzyskać nowe pliki .tar.gz, pozostawiając wcześniejsze pliki .tar.gz w spokoju? Spróbuj dodać „tmstamp = $ (data '+% Y% m% d-% H% M')” i zmień $ {base} na $ {base} - $ {tmstamp}.
freiheit
2
@EarthMind: jeśli zamierzasz umieścić wszystko w jednym wierszu, upewnij się, że przed poleceniem tar znajduje się średnik (;). W przeciwnym razie baza jest przekazywana do tar jako zmienna środowiskowa, zamiast być zmienną pomocniczą powłoki.
Juliano
@mwojtera, twoja próba edycji powinna być własną odpowiedzią
pisklęta
10

Co powiesz na to: find * -maxdepth 0 -type d -exec tar czvf {}.tar.gz {} \;

Objaśnienie: Uruchomisz wyszukiwanie na wszystkich elementach w bieżącym katalogu. Maxdepth 0 sprawia, że ​​nie będzie się powtarzać niżej niż podane argumenty. (W tym przypadku * lub wszystkie elementy w bieżącym katalogu) Argument „d” dla „-type” pasuje tylko do katalogów. Następnie exec uruchamia tar na dowolnych dopasowaniach. ({} zastępuje się pasującym plikiem)

Christopher Karel
źródło
1
Ale wciąż pojawia się błąd, że podana ścieżka jest katalogiem, a nie plikiem
EarthMind
3
Sam gzip nie archiwizuje katalogów
Juliano
Musisz spakować katalogi, zanim będziesz mógł je zgzipować.
ℝaphink
1
Potrzebujesz katalogu z opcją Z, a nie prostego gzip dla katalogów. Jednak bardzo miłe użycie find.
freiheit
3
Błąd: „find: ścieżki muszą poprzedzać wyrażenie:;” Pierwsza część działa, więc użyłem (tylko katalogi): for dir in `find * -maxdepth 0 -type d`; do tar -cvzf ${dir}.tar.gz ${dir}; done
JosephK
4

Spowoduje to utworzenie pliku o nazwie blah.tar.gz dla każdego pliku w katalogu o nazwie blah.

$ cd directory
$ for dir in `ls`; do tar -cvzf ${dir}.tar.gz ${dir}; done

Jeśli masz w katalogu więcej niż tylko katalogi (tzn. Także pliki, ponieważ ls zwróci wszystko w katalogu), użyj tego:

$ cd directory
$ for dir in `find . -maxdepth 1 -type d  | grep -v "^\.$" `; do tar -cvzf ${dir}.tar.gz ${dir}; done

Grep -v wyklucza bieżący katalog, który finddomyślnie pojawi się w poleceniu.

Philip Reynolds
źródło
3
Zarówno ls, jak i find NIE zostały stworzone do użycia w ten sposób. W szczególności chodzi o prezentowanie plików na liście czytelnej dla użytkownika, a nie generowanie list plików jako argumentów dla „for”. Wystarczy użyćfor dir in *
Juliano
1
Wypróbowałem twoją pierwszą sugestię, ale nie działa ona z katalogami zawierającymi spacje w ich nazwie
EarthMind
Co więcej, pierwsze polecenie utworzy archiwum tar dla każdego pliku w katalogu.
ℝaphink