我有一个巨大的 MySQL 备份文件(来自 mysqldump),其中的表按字母顺序排列。我的恢复失败,我想从备份文件中的下一个表开始。(我已经纠正了这个问题,这实际上并不是一个关于 MySQL 恢复等的问题。)
我想做的是获取我的备份文件,例如backup.sql
并修剪文件的开头,直到看到这一行:
-- Table structure for `mytable`
Run Code Online (Sandbox Code Playgroud)
然后之后的所有内容都将最终出现在我的结果文件中,例如backup-secondhalf.sql
. 由于文件是 bzip2 压缩的,这有点复杂,但这应该不是什么大问题。
我想我可以这样做:
$ bunzip2 -c backup.sql.bz2 | grep --text --byte-offset --only-matching -e '--Table structure for table `mytable`' -m 1
Run Code Online (Sandbox Code Playgroud)
这将为我提供文件中我想要修剪的字节偏移量。然后:
$ bunzip2 -c backup.sql.bz2 | dd skip=[number from above] | bzip2 -c > backup-secondhalf.sql.bz2
Run Code Online (Sandbox Code Playgroud)
不幸的是,这需要我在文件上运行 Bunzip2 两次并读取所有这些字节两次。
有没有办法一次性完成这一切?
我不确定我的 sed-fu 是否足够强大来执行“删除正则表达式之前的所有行,然后让文件的其余部分通过”表达式。
这是在 Debian Linux 上,所以我有可用的 GNU 工具。
bunzip2 -c backup.sql.bz2 | \
sed -n '/-- Table structure for `mytable`/,$p'
Run Code Online (Sandbox Code Playgroud)
解释:
-n suppress automatic printing of pattern space
Run Code Online (Sandbox Code Playgroud)
地址范围构建:从正则表达式开始
/-- Table structure for `mytable`/
Run Code Online (Sandbox Code Playgroud)
结束于
$ Match the last line.
Run Code Online (Sandbox Code Playgroud)
命令
p Print the current pattern space.
Run Code Online (Sandbox Code Playgroud)
编辑:根据您转储数据库的方式,您可能会有很长的行。GNU sed 可以根据可用内存量来处理它们。
小智 0
我想知道这样的事情是否可以解决问题:
use strict;
use warnings;
use feature 'say';
use IO::Uncompress::Bunzip2 '$Bunzip2Error';
my $file = $ARGV[0] // die "need a file";
my $zh = IO::Uncompress::Bunzip2->new( $file, {
AutoClose => 1,
Transparent => 1,
} ) or die "IO::Uncompress::Bunzip2 failed: $Bunzip2Error\n";
my $trigger = undef;
while ( <$zh> ) {
chomp;
$trigger = 1 if $_ eq '-- Dumping data for table `experiments`';
say if $trigger;
}
Run Code Online (Sandbox Code Playgroud)
所以基本上它会在模式之后开始打印内容,也可以将其直接通过管道传输到 bzip2/gzip,就像perl chop.pl input_sql.bz2 | bzip2 > out.sql.bz2
您在 Debian 上需要的那样libio-compress-perl
。