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возвращает имя каждого обычного файла.


Почему *.*в 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.


1
просто прочитайте, что -name должно стоять перед -type, чтобы избежать вызова stat для каждого файла.

@Ben Имеет смысл, хороший вклад! Для больших деревьев это может быть заметно.
Plundra



Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.