Назад | Перейти на главную страницу

Как использовать bzdiff, чтобы найти разницу между двумя сжатыми файлами с помощью опции diff -I?

Я пытаюсь выполнить сравнение дампов MySQL (созданных с помощью mysqldump и переданных в bzip2), чтобы увидеть, есть ли изменения между последовательными дампами. Далее следуют хвосты двух дампов:

tmp1:

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2011-03-11  1:06:50

tmp2:

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2011-03-11  0:40:11

Когда я bzdiff их bzip-версию:

$ bzdiff tmp?.bz2 
10c10
< -- Dump completed on 2011-03-11  1:06:50
---
> -- Dump completed on 2011-03-11  0:40:11

Согласно руководству по bzdiff, любая опция, переданная в bzdiff, передается в diff. Поэтому я посмотрел на параметр -I, который позволяет определять регулярное выражение; соответствующие ему строки игнорируются в diff. Когда я тогда попробую:

$ bzdiff -I'Dump' tmp1.bz2 tmp2.bz2

Я получаю пустую разницу. Я хотел бы, тем не менее, максимально сопоставить строку «Дамп завершен», но когда я попытаюсь:

$ bzdiff -I'Dump completed' tmp1.bz2 tmp2.bz2
diff: extra operand `/tmp/bzdiff.miCJEvX9E8'
diff: Try `diff --help' for more information.

То же самое происходит с некоторыми вариациями:

$ bzdiff '-IDump completed' tmp1.bz2 tmp2.bz2
$ bzdiff '-I"Dump completed"' tmp1.bz2 tmp2.bz2
$ bzdiff -'"IDump completed"' tmp1.bz2 tmp2.bz2

Если я различаю файлы, не распакованные в bzip, проблем нет:

$diff -I'^[-][-] Dump completed on' tmp1 tmp2

дает также пустой diff.

bzdiff - это сценарий оболочки, обычно помещаемый в / bin / bzdiff. По сути, он анализирует параметры команды и передает их в diff следующим образом:

OPTIONS=
FILES=
for ARG
do
    case "$ARG" in
    -*) OPTIONS="$OPTIONS $ARG";;
     *) if test -f "$ARG"; then
            FILES="$FILES $ARG"
        else
            echo "${prog}: $ARG not found or not a regular file"
            exit 1
        fi ;;
    esac
done
[...]
bzip2 -cdfq "$1" | $comp $OPTIONS - "$tmp"

Я думаю, проблема связана с побегом из пробелов при прохождении $OPTIONS to diff, но я не мог понять, как его правильно интерпретировать.

Любые идеи?

РЕДАКТИРОВАТЬ @DerfK: Хорошая точка зрения на ., Я забыл о них ... Я попробовал предложение с несколькими уровнями кавычек, но оно все еще не распознается:

$ bzdiff "-I'\"Dump.completed.on\"'" tmp1.bz2 tmp2.bz2
diff: extra operand `/tmp/bzdiff.Di7RtihGGL'

Я нашел решение этой проблемы. Bzdiff некорректно выполнял парсинг опций и отправку в diff; перед первым вариантом был добавлен пробел, который, кажется, подбрасывает вещи в воздух ...

Я внес следующие изменения в bzdiff:

$ diff bzdiff_orig /bin/bzdiff 
27c27,31
<     -*)   OPTIONS="$OPTIONS $ARG";;
---
>     -*)   if test -z "$OPTIONS"; then
>       OPTIONS="$ARG"
>         else
>             OPTIONS="$OPTIONS $ARG"
>         fi ;;
57c61
<                         bzip2 -cdfq "$1" | $comp $OPTIONS - "$tmp"
---
>                         bzip2 -cdfq "$1" | $comp "$OPTIONS" - "$tmp"

С измененным кодом сравнение продолжается, как ожидалось:

$ bzdiff -I"Dump completed" tmp?.bz2
$ bzdiff -I"This should not match" tmp?.bz2
9c9
< -- Dump completed on 2011-03-11  1:06:50
---
> -- Dump completed on 2011-03-11  0:40:11

Я отправлю электронное письмо разработчику bzip с сообщением об ошибке.

Никакое цитирование в этом не поможет; цитирование происходит не на том уровне. bzgrep -e -I'Dump completed' или bzgrep -- -I'Dump completed' должно сработать.

На этом этапе я бы отказался от пробелов и использовал Dump.completed таким образом . соответствует пробелу (так как это регулярное выражение).

Bash удаляет слой кавычек каждый раз, когда оценивает аргумент, а также удаляет слой кавычек из того, что вы вводили, когда нажимаете return. С тех пор case Заявление настаивает на том, чтобы вариант начинался с -, вам нужно попробовать что-то вроде "-'\"IDump completed\"'" так что bzdiff выполняется с аргументом -'"IDump completed"' который следует вставить в строку $ OPTIONS как -"IDump completed" что должно привести к выполнению diff с -IDump completed как один аргумент вместо двух слов.