我正在尝试对 MySQL 转储(使用 mysqldump 创建并传送到 bzip2)进行差异分析,以查看连续转储之间是否存在变化。以下是 2 个转储的尾部:
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 比较它们的 bzip2 版本时:
$ 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
我得到了一个空的 diff。我想尽可能多地匹配“转储完成”行,但是当我尝试时:
$ 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
如果我对解压后的文件进行差异分析,则没有问题:
$diff -I'^[-][-] Dump completed on' tmp1 tmp2
还给出了一个空的差异。
bzdiff 是一个 shell 脚本,通常放在 /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
diff 时转义空格,但我不知道如何正确解释它。
有任何想法吗?
编辑
@DerfK: 说得好.
,我已经忘记了它们...我尝试了使用多级引号的建议,但仍然无法识别:
$ bzdiff "-I'\"Dump.completed.on\"'" tmp1.bz2 tmp2.bz2
diff: extra operand `/tmp/bzdiff.Di7RtihGGL'
答案1
此时我会放弃空格并使用Dump.completed
. 与空格匹配(因为这是一个正则表达式)。
Bash 每次评估参数时都会删除一层引号,当您按下回车键时也会删除您输入的内容中的一层引号。由于该case
语句坚持选项以 - 开头,因此您需要尝试类似这样的操作,以便使用应插入 $OPTIONS 行中的"-'\"IDump completed\"'"
参数执行 bzdiff ,这应该会导致 diff作为单个参数而不是两个单词执行。-'"IDump completed"'
-"IDump completed"
-IDump completed
答案2
无论引用多少次都无济于事;引用发生在错误的层面。 bzgrep -e -I'Dump completed'
或者bzgrep -- -I'Dump completed'
应该起作用。
答案3
我找到了这个问题的解决方案。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 开发人员以提交错误报告。