gzip wszystkie pliki bez usuwania ich


11

Muszę oddzielnie rozpakować wszystkie pliki w katalogu, w tym wszystkie pliki w podkatalogach, bez późniejszego usuwania oryginałów. Powiedzmy, że mam index.html, chcę mieć na końcu index.html.gzip ORAZ index.html.

Jestem w stanie zgzipować wszystkie pliki w moim katalogu poprzez

gzip -r .

Ale chcę również zachować oryginalne pliki.

czy to możliwe?

Odpowiedzi:


9
find . -type f | \
while read -r x
do
  gzip -c "$x" > "$x.gz"
done

-cOdkłada wynik na standardowe wyjście i zachowuje oryginalny sam. Wadą jest to, że musisz sam znaleźć pliki. Jednak w celu bardziej zaawansowanego przechodzenia można użyć find(1), jak wyżej: .wyszukiwania zaczynających się od bieżącego katalogu i -type fzwracających nazwę każdego zwykłego pliku.


Dlaczego *.*w ls?

@pooh: *.*pasuje do wszystkich plików o regularnych nazwach i zwykle nie ma katalogów. Oczywiście działa tylko w większości przypadków i zwykle nie, jeśli jest to potrzebne. Następnie użyj findpolecenia.
Boldewyn

@Boldewyn: pytanie dotyczyło spakowania wszystkich plików w katalogu. ls *.*nie wybiera plików takich jak TODO .

lsnie jest potrzebna w ogóle : for x in *. Jednak używanie findpowinno być find . -type f | while read -r x.
Wstrzymano do odwołania.

Zaktualizowana odpowiedź. Dzięki za -rwłączenie read.
Boldewyn

5
find . -type f -not \( -name '*.gz' -or -name '*[~#]' \) -exec sh -c 'gzip -c "{}" > "{}.gz"' \;

Możesz łatwo to zmienić, aby uwzględnić to, co chcesz skompresować ( -name '*.txt -or -name '*.htmlitp.) Zamiast teraz, z wyłączeniem niektórych plików (już skompresowanych, kopii zapasowych i plików tymczasowych).

Dobrze radzi sobie również ze spacjami w nazwie pliku.

Zmień gzipna echo gzipdo testowania. Lub pomiń część -exec razem.

Edycja: Och, zapomniałem wspomnieć, że to nie sprawdza, czy <target>.gzjuż istnieje. Może to stanowić problem.

Edycja2: Ok, zaczynamy od czegoś, co sprawdza istniejący plik. Jeśli to może być potrzebne. Przebacz oneliney-ness.

while read file; do if [ ! -f "$file.gz" ]; then echo "Compressing $file"; gzip -c "$file" > "$file.gz"; else echo "Not overwriting $file.gz";  fi  done < <(find . -type f -not \( -name '*.gz' -or -name '*[~#]' \))

Moje find-foo może nie jest tym, czym mogłoby być, bardzo możliwe, że można pominąć bezpośrednio w znalezieniu.


1
po prostu przeczytaj, że -name powinna pojawić się przed opcją -type, aby uniknąć wywołania statystyki dla każdego pliku.

@Ben Ma sens, dobry wkład! W przypadku dużych drzew może to być zauważalne.
plundra



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.