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?


źródło

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.

Boldewyn
źródło
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.

plundra
źródło
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
2

Po prostu dodaj opcję -c, myślę, że to powinno działać

Ken Wayne Vander Linde
źródło
1
Prawdopodobnie działa to tylko podczas gzipowania pojedynczego pliku na raz.
its_me
0
gzip -rc `ls` > archive.gz

Testowane na Debianie (gzip 1.3.12-6)

tannerli
źródło
To tworzy jedno archiwum. OP chce osobnych archiwów. lsjest niepotrzebne, użyj *.
Wstrzymano do odwołania.