Как сказать gzip сохранить оригинальный файл?

210

Я хотел бы сжать текстовый файл с помощью инструмента командной строки gzip, сохранив исходный файл. По умолчанию выполняется следующая команда

gzip file.txt

приводит к изменению этого файла и переименованию его file.txt.gz. вместо этого поведения я хотел бы иметь этот новый сжатый файл в дополнение к существующему file.txt. Сейчас я использую следующую команду, чтобы сделать это

gzip -c file.txt > file.txt.gz

Это работает, но мне интересно, почему нет более простого решения для такой общей задачи? Может быть, я упустил возможность сделать это?

Мануэль Сельва
источник
3
Это потому, что gzip сжимает данный файл и создает новый файл. Сжатие означает сжатие исходного файла и его замену новым. Ваш параметр -c явно указывает gzip сохранить его под другим именем. Вот почему это работает
ШВ
@SHW Я не получил твой комментарий ...?
Мануэль Сельва
@ManuelSelva, когда исходный файл сжат, он больше не нужен, я думаю, это был дизайн.
маргаритка
2
Почему gzip / gunzip делает это по умолчанию, когда никакой другой инструмент unix не делает это вне меня.
Матин Улхак

Ответы:

247

Для GNU gzip1.6 или выше, FreeBSD и производных или последних версий NetBSD, смотрите ответ don_cristi .

В любой версии вы можете использовать перенаправления оболочки, как в:

gzip < file > file.gz

Если аргумент не задан, он gzipчитает его стандартный ввод, сжимает его и записывает сжатую версию в стандартный вывод. В качестве бонуса, при использовании перенаправлений оболочки вам не нужно беспокоиться о вызываемых файлах "--help"или "-"(этот последний по-прежнему остается проблемой gzip -c --).

Еще одним преимуществом gzip -c file > file.gzявляется то, что если fileне удается открыть, команда не будет выполнена без создания пустого file.gz(или перезаписи существующего file.gz) и без выполнения gzipвообще.

Существенная разница по сравнению с gzip -kтем, что не будет попытки скопировать fileметаданные (владельца, разрешения, время модификации, имя несжатого файла) в file.gz.

Также, если он file.gzуже существует, он будет автоматически переопределять его, если вы не включили noclobberопцию в своей оболочке ( set -o noclobberнапример, в оболочках POSIX).

Стефан Шазелас
источник
4
Теперь это касается специфики вопроса ОП и отвечает на общий вопрос «Как сказать gzip сохранить исходный файл». Очень удобно и полезно чем -c.
Codewaggle
8
Обратите внимание, что <и> фактически должны быть введены в команду и не представляют заполнитель для имени файла
Гаурав Гупта,
1
Какой -kвариант? Не удалось найти его на страницах руководства, например, здесь эта версия linux.die.net/man/1/gzip . Кроме того, похоже, что по умолчанию gzip копирует метаданные файла.
flow2k
1
@ flow2k, это ссылка на ответ don_cristi.
Стефан Шазелас
ах, я вижу это на своих макросах, но очень жаль, что это не на RHEL и не на Ubuntu. Благодарю.
flow2k
138

Обратите внимание, что недавно выпущенная (июнь 2013 г.) «принимает опцию --keep (-k) для согласованности с такими инструментами, как xz, lzip и bzip2. С этой опцией gzip больше не удаляет именованные входные файлы при сжатии или распаковке» .gzip-1.6

Выдержка из справочной страницы:

  -k --keep
         Keep (don't delete) input files during compression or decompression.

Таким образом, 1.6вы можете использовать -kили --keepсохранить исходный файл:

gzip -k -- "$file"

(обратите внимание, что он не работает, если $fileесть -(что gzipинтерпретирует как значение stdin вместо фактического вызываемого файла -), в этом случае вы должны изменить его на ./-)

Эта опция была впервые представлена ​​в реализации FreeBSDgzip (во FreeBSD 7.0 в 2007 году) для обеспечения соответствия bzip2. Это gzipосновано на переписывании GNU gzipNetBSD. -kВариант в конце концов сделал это назад к NetBSD в 2010 году .

don_crissti
источник
10
Geez. RHEL6 поставляется только с базой zip 1.3.12 ...
Николас Толи Коттрелл
Это работает на Mac / OS X :) (это BSD)
Пол
Много ли стандартных дистрибутивов больше не используют> = 1.6? Хотите знать , если ответ нужен Обновит
MichaelChirico
Для чего "-"? Я думаю, что gzip -k "file" работает нормально.
notilas
3
@notilas, см. unix.stackexchange.com/q/11376/22142
don_crissti
30

Из документации кажется, что нет возможности создать копию файла.

Вы можете определить функцию оболочки

gzipkeep() {
    if [ -f "$1" ] ; then
        gzip -c -- "$1" > "$1.gz"
    fi
}

а потом

gzipkeep file.txt
Matteo
источник
2
Обратите внимание, что если файл есть -, вы должны назвать его как gzipkeep ./-.
Стефан Шазелас