эффективный способ объединить заголовочный файл и часть хвостового файла, а затем в стандартный вывод - PullRequest
2 голосов
/ 25 июня 2010

На самом деле я в большой агонии, восстанавливая поврежденный файл gzip, возможно, из-за прерванной передачи FTP, а затем возобновил. После поиска в Google я нашел Восстановление поврежденного .gz файла и пытаюсь, как он читает.

То, что я сейчас делаю, - это объединение файла заголовка gzip с какой-то последней частью поврежденного файла, изменяя размер последней части. Затем я проверяю объединенный файл как вход для gunzip, если он может дать значимый результат. Я написал сценарий, и следующее - лучшее, что я могу перенаправить слияние в gunzip. Какой более эффективный способ перенаправить содержимое файла в gzip? Я думаю, вы не должны создавать какие-либо файлы. ($ i - это переменная размера)

cat head > x.gz; tail -c $i tail >> x.gz; gzip -t x.gz 2>&1 1>/dev/null

Ответы [ 2 ]

1 голос
/ 25 июня 2010

То же, но без временного файла:

for ((i=0; i<$TAIL_FILE_SIZE; $i++)); do
  ( cat head; tail -c $i tail ) | gzip -t &>/dev/null && { echo "TEST OK: $i"; break; }
done

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

В твоем случае я думаю tail -c должно быть в порядке. Многие инструменты GNU (включая хвост) имеют довольно большую производительность, помогающую оптимизировать. Например. на моем SUSE в офисе tail -c использовал mmap () для доступа к входному файлу.

В противном случае для чтения файла со смещением обычно используется dd.

P.S. В Perl вы можете прочитать файлы head и tail в память, а затем с помощью substr () попробовать передать фрагменты в некоторую библиотеку gzip из CPAN. (Я почти уверен, что для Perl есть библиотеки gzip, но я не использовал их. Google показывает сразу несколько обращений.) Таким образом, вы могли бы уменьшить накладные расходы, убрав запуск процессов и перечитывание файлов.

0 голосов
/ 25 июня 2010

Вот исправленная версия вашей команды:

cp head x.gz; tail -c $i tail >> x.gz; gzip -t x.gz >/dev/null 2>&1 

Перенаправляя весь вывод в /dev/null, вы полагаетесь исключительно на код завершения gzip для результата проверки целостности, так как никакие сообщения не будут выводиться на терминал. Обратите внимание, что порядок перенаправления является значительным.

Если вы не хотите создавать промежуточный файл:

cat head <(tail -c $i tail) | gzip -t >/dev/null 2>&1

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...