Есть ли способ заставить gzip не перезаписывать файлы при конфликте?

17

Я пишу сценарий, в котором я разархивирую файлы.

Существует возможность, что я могу заархивировать файл, создать файл с тем же именем и попытаться также сжать его, например:

$ ls -l archive/
total 4
-rw-r--r-- 1 xyzzy xyzzy  0 Apr 16 11:29 foo
-rw-r--r-- 1 xyzzy xyzzy 24 Apr 16 11:29 foo.gz

$ gzip archive/foo
gzip: archive/foo.gz already exists; do you wish to overwrite (y or n)? n   
    not overwritten

Используя gzip --force, я могу заставить gzip перезаписать foo.gz, но в этом случае я думаю, что есть большая вероятность, что я могу потерять данные, если перезаписать foo.gz. Кажется, что нет переключателя командной строки, чтобы заставить gzip оставлять .gzфайлы в покое ... неинтерактивная версия нажатия 'n' в приглашении.

Я пытался gzip --noforceи gzip --no-force, надеясь, что они могут соответствовать стандарту опций GNU, но ни один из них не сработал.

Есть ли прямой обходной путь для этого?

Редактировать:

Оказывается, это один из случаев, когда стоит прочитать информационную страницу, а не справочную страницу.

Со страницы информации:

`--force'
`-f'
     Force compression or decompression even if the file has multiple
     links or the corresponding file already exists, or if the
     compressed data is read from or written to a terminal.  If the
     input data is not in a format recognized by `gzip', and if the
     option `--stdout' is also given, copy the input data without
     change to the standard output: let `zcat' behave as `cat'.  If
     `-f' is not given, and when not running in the background, `gzip'
     prompts to verify whether an existing file should be overwritten.

На странице руководства отсутствовал текст, и когда он не работал в фоновом режиме

При работе в фоновом режиме, gzip не будет запрашивать и не будет перезаписывать, пока не -fбудет вызвана опция.

Бартон Читтенден
источник
3
Я не уверен, как gzip проверяет наличие фона, но добавление '&' в bash в системе, над которой я работаю, этого не делает. Нахождение на другой стороне трубы, кажется, работает, хотя вместо этого: find ./ ! -name "*gz" -exec gzip {} \; & это работает: find ./ ! -name "*gz" -print0 | xargs -0 -n 1 -t gzip gzip сообщает: gzip: ./2012-July.txt.gz already exists; not overwritten
Билл МакГонигл
1
@BillMcGonigle Ваш комментарий должен быть ответом!
Rockallite

Ответы:

9

До меня дошло, что лучший способ избежать нежелательного эффекта - не просить программу выполнить нежелательный эффект. То есть просто не говорите ему сжимать файл, если файл уже присутствует в сжатом виде.

например:

if [ ! -f "$file.gz" ]; then 
    gzip "$file"; 
else 
    echo "skipping $file"
fi

или короче (запустите, trueесли есть файл .gz, сожмите файл в противном случае)

[ -f "$file.gz" ] && echo "skipping $file" || gzip "$file"    
Ярослав Рахматуллин
источник
К сожалению, это выполняется как системная команда внутри perl-скрипта (длинный рассказ о том, почему мы не используем что-то вроде IO :: Compress :: Gzip, поверьте мне, я думал об этом). Сама команда сжатия сохраняется в файле конфигурации. Ваша последняя команда выглядит близко к тому, что мне нужно, но я думаю, что нашел что-то, что будет соответствовать моим потребностям, чуть лучше. Я приму ваш ответ, потому что это лучшее общее решение, чем мое, но посмотрите, что я собираюсь использовать ниже.
Бартон Читтенден
Вы можете сунуть файл в Perl ...
Ярослав Рахматуллин
1
Я не понимаю, что вы имеете в виду poke a file.
Бартон Читтенден
Отсутствие ассоциации / использования имиджа в повседневном общении на американском английском удивляет меня каждый раз :) Позвольте мне попытаться объяснить. Придумай образ ребенка, тыкающего мертвую ворону палкой, чтобы увидеть, жив он или нет. Poking используется для поиска атрибутов здесь. Точно так же тыкание файла означало бы проверить что-то об этом, например, если оно вообще присутствует. Во всяком случае, я считаю, что действие пощипывания должно, по крайней мере, означать «достичь контакта с внешним объектом» , и этого достаточно, чтобы сказать «получить некоторую информацию о файле» с изображением, а не излагать его по буквам.
Ярослав Рахматуллин
«poke» - это часто хакерский сленг для определения места в памяти. См .: en.wikipedia.org/wiki/PEEK_and_POKE#Generic_usage_of_.22POKE.22
Билл МакГонигл,
12

Самая близкая вещь, которую я мог найти к единственной команде, состоит в следующем:

yes n | gzip archive/foo

Команда yesпечатает, yа затем перевод строки на стандартный вывод, пока не получит сигнал. Если у него есть аргумент, он напечатает его вместо y. В этом случае он печатает nдо выхода gzip, тем самым закрывая трубу.

Это эквивалентно nмногократному вводу с клавиатуры; это автоматически ответит на вопросgzip: archive/foo.gz already exists; do you wish to overwrite (y or n)?

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

Бартон Читтенден
источник
1
еще одно раздражение в том, что gzipвыходит2
Стивен Пенни