gzip все файлы без их удаления

11

Мне нужно сжать все файлы в директории отдельно, включая все файлы в подкаталогах без последующего удаления оригиналов. Допустим, у меня есть index.html, в конце я хочу иметь index.html.gzip AND index.html.

Я могу распаковать все файлы в моем каталоге через

gzip -r .

Но я хочу сохранить оригинальные файлы также.

Это возможно?


источник

Ответы:

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

-cПомещает результат в стандартный вывод и сохраняет оригинальные один. Недостатком является то, что вам нужно найти файлы самостоятельно. Однако для более сложного обхода вы можете использовать find(1), как указано выше: .поиск, начиная с текущего каталога, и -type fвозвращает имя каждого обычного файла.

Boldewyn
источник
Почему *.*в ls?
@pooh: *.*соответствует всем регулярно именуемым файлам и обычно не содержит каталогов. Конечно, это работает только в большинстве случаев и обычно не, если вам это нужно. Затем используйте findкоманду.
Болдевин
@Boldewyn: вопрос заключался в том, чтобы сжать все файлы в директории. ls *.*не будет выбирать файлы, такие как TODO .
lsне требуется вообще : for x in *. Тем не менее, использование findдолжно быть find . -type f | while read -r x.
Приостановлено до дальнейшего уведомления.
Обновленный ответ. Спасибо за -rвключение read.
Болдевин
5
find . -type f -not \( -name '*.gz' -or -name '*[~#]' \) -exec sh -c 'gzip -c "{}" > "{}.gz"' \;

Вы можете легко переключать его, чтобы включить то, что вы хотите сжать ( -name '*.txt -or -name '*.htmlи т. Д.), А не как сейчас, за исключением некоторых файлов (уже сжатых, резервных и временных файлов).

Обрабатывает пробелы в имени файла тоже очень хорошо.

Изменение gzipк echo gzipдля тестирования. Или пропустите часть -exec все вместе.

Изменить: О, я забыл упомянуть, что это не проверяет, если <target>.gzуже существует. Это может или не может быть проблемой.

Edit2: Хорошо, здесь мы идем с чем-то, что проверяет существующий файл. Если это может быть желательно. Прошу прощения за единственность.

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 '*[~#]' \))

Мой find-foo, возможно, не то, что может быть, вполне возможно пропустить непосредственно в find.

plundra
источник
1
просто прочитайте, что -name должно стоять перед -type, чтобы избежать вызова stat для каждого файла.
@Ben Имеет смысл, хороший вклад! Для больших деревьев это может быть заметно.
Plundra
2

Просто добавьте опцию -c, я думаю, что это должно работать

Кен Уэйн ВандерЛинде
источник
1
Это, вероятно, работает только при сжатии одного файла за раз.
its_me
0
gzip -rc `ls` > archive.gz

Протестировано на Debian (gzip 1.3.12-6)

tannerli
источник
Это создает один архив. ОП хочет отдельные архивы. lsненужно, используйте *.
Приостановлено до дальнейшего уведомления.