Как убедиться, что исходный файл и gzip-версия не совпадают - PullRequest
0 голосов
/ 11 июня 2011

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

Но текстовые файлы передаются на ПК для целей резервного копирования ежедневно , где они сжаты gzip, даже до того, как они закончили расти.

Это означает, что у меня часто есть и file.txt, и сжатая форма file.txt.gz, где несжатый файл может быть более свежим, чем сжатая версия.

Я решаю, какой из них придерживаться следующего bash script gzandrm:

#!/usr/bin/bash

# Given an uncompressed file, look in the same directory for 
# a gzipped version of the file and delete the uncompressed 
# file if zdiff reveals they're identical. Otherwise, the 
# file can be compressed.

# eg:  find . -name '*.txt' -exec gzandrm {} \;

if [[ -e $1 && -e $1.gz ]] 
then

    # simple check: use zdiff and count the characters
    DIFFS=$(zdiff "$1" "$1.gz" | wc -c)

    if [[ $DIFFS -eq 0 ]] 
    then

        # difference is '0', delete the uncompressed file
        echo "'$1' already gzipped, so removed"
        rm "$1"

    else

        # difference is non-zero, check manually
        echo "'$1' and '$1.gz' are different"

    fi

else
    # go ahead and compress the file
    echo "'$1' not yet gzipped, doing it now"
    gzip "$1"
fi

, и это сработало хорошо, но было бы более разумно сравнивать даты изменения файлов, поскольку gzip не изменяет дату изменения при сжатии, поэтому два файла с одинаковой датой действительно являются одним и тем же файлом, даже если один из них сжат.

Как изменить скрипт для сравнения файлов по дате , а не размеру ?

Ответы [ 2 ]

1 голос
/ 11 июня 2011

Не совсем ясно, какова цель, но это кажется простой эффективностью, поэтому я думаю, что вы должны сделать два изменения: 1) проверить время модификации, как вы предлагаете, и не беспокоить сравнение содержимого, если несжатый файл не новее, чем сжатый файл, и 2) используйте zcmp вместо zdiff.

Взяв # 2 первым, ваш скрипт делает это:

DIFFS=$(zdiff "$1" "$1.gz" | wc -c)
if [[ $DIFFS -eq 0 ]]

, которая выполнит полный анализ потенциально больших файлов, подсчитает символы в выводе diff и проверит количество. Но все, что вы действительно хотите знать, это то, отличается ли контент. cmp лучше для этого, так как он будет сканировать побайтово и останавливаться, если обнаружит разницу. Не нужно времени, чтобы отформатировать хорошее текстовое сравнение (которое вы в основном игнорируете); его статус выхода говорит вам результат. zcmp не так эффективен, как raw cmp, поскольку сначала нужно будет распаковать, но у zdiff такая же проблема.

Таким образом, вы можете переключиться на zcmp (и исключить использование подоболочки, исключить wc, не вызывать [[ и избежать помещения потенциально больших текстовых различий в переменную), просто изменив две вышеупомянутые строки на это:

if zcmp -s "$1"    # if $1 and $1.gz are the same

Чтобы пойти дальше и сначала проверить время модификации, вы можете использовать опцию -nt (новее) для команды test (также известной как квадратная скобка), переписав приведенную выше строку следующим образом:

if [ ! "$1" -nt "$1.gz" ] || zcmp -s "$1"

, в котором говорится, что если несжатая версия не новее сжатой версии ИЛИ, если они имеют одинаковое содержимое, то $ 1 уже распакован, и вы можете удалить его. Обратите внимание, что если несжатый файл не новее, zcmp не будет работать вообще, сохраняя некоторые циклы.

Остальная часть вашего скрипта должна работать как есть.

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

1 голос
/ 11 июня 2011

Вы можете легко сравнить отметку даты файла, используя stat со строками формата %Y или %Z, чтобы получить время последней модификации или изменения в секундах с начала эпохи.

if [ $(stat -c %Z $1) -eq ($stat -c %Z $1.gz) ]; then
    echo "Last changed time of $1 is the same as $1.gz"
fi
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...