作用:
通过 perl 脚本匹配出 mysqldump全备文件中的某个库的某几个表。
经测试perl是shell的N倍
208G的文件需要47分钟
vim test.pl #!/usr/bin/perl use strict; use warnings; # mysqldump 文件路径 my $dump_file = "/tmp/test.sql"; # 输出文件路径 my $output_file = "/tmp/filter.sql"; # 需要获取的库 my $database = 'database'; # 需要获取的表 多个表用逗号分隔 my $tables = "t1,t2,t3,t4,t5"; ############################################################################################################## my $database_switch = 0; my $table_switch = 0; # 保存旧的IFS值 my $OLD_IFS = $,; # 将IFS设置为逗号 $, = ','; # 将逗号分隔的字符串拆分成数组 my @table_array = split(/,/, $tables); # 恢复IFS为旧值 $, = $OLD_IFS; # 对表格数组进行排序 @table_array = sort @table_array; if (-e $output_file) { die "输出文件 $output_file 已存在,请确认文件内容后删除文件并重新执行脚本\n"; } open my $out_fh, '>', $output_file or die "无法打开输出文件 $output_file: $!\n"; open my $dump_fh, '<', $dump_file or die "无法打开输入文件 $dump_file: $!\n"; # 读取文件的前18行 for (my $i = 0; $i < 18; $i++) { my $line = <$dump_fh>; last unless defined $line; print $out_fh $line; } # 使用while循环读取文件的每一行 while (my $line = <$dump_fh>) { chomp $line; if ($line =~ /^-- Current Database: \`$database\`$/) { $database_switch = 1; } elsif ($line =~ /^-- Current Database:/ && $line !~ /^-- Current Database: \`$database\`$/) { $database_switch = 0; } foreach my $table (@table_array) { if ($line =~ /^-- Table structure for table \`${table}\`$/) { $table_switch = 1; last; } elsif ($line =~ /^-- Table structure for table/ && $line !~ /^-- Table structure for table \`${table}\`$/) { $table_switch = 0; } } if ($database_switch == 1 && $table_switch == 1) { print $out_fh "$line\n"; } } # 使用反引号获取tail命令的输出 my $result = `tail -n 11 $dump_file`; print $out_fh $result; close $dump_fh; close $out_fh; print "转储完成保存在 $output_file\n";
运行
chmod +x test.pl ./test.pl
这个是shell 版本的
#!/bin/bash # mysqldump 文件路径 dump_file="/tmp/test.sql" # 输出文件路径 output_file="/tmp/filter.sql" # 需要获取的库 database='database' # 需要获取的表 多个表用逗号分隔 tables="t1,t2,t3,t4,t5" database_switch=0 table_switch=0 # 保存旧的IFS值 OLD_IFS=$IFS # 将IFS设置为逗号 IFS=',' # 将逗号分隔的字符串拆分成数组 table_array=($tables) # 恢复IFS为旧值 IFS=$OLD_IFS # 对表格数组进行排序 table_array=($(printf '%s\n' "${table_array[@]}" | sort)) if [[ -e "${output_file}" ]]; then echo "输出文件 ${output_file} 已存在,请确认文件内容后删除文件并重新执行脚本" exit 1 fi head -n 18 ${dump_file} >${output_file} # 使用while循环读取文件的每一行 while IFS= read -r line; do if [[ "${line}" == "-- Current Database: \`$database\`" ]]; then database_switch=1 elif [[ "${line}" == "-- Current Database:"* && "${line}" != "-- Current Database: \`$database\`" ]]; then database_switch=0 fi for table in "${table_array[@]}"; do if [[ "${line}" == "-- Table structure for table \`${table}\`" ]]; then table_switch=1 break elif [[ "${line}" == "-- Table structure for table"* && "${line}" != "-- Table structure for table \`${table}\`" ]]; then table_switch=0 fi done if [[ ${database_switch} -eq 1 && ${table_switch} -eq 1 ]]; then #echo "${line} (Table: ${table})" echo "${line}" >> "${output_file}" fi done < "$dump_file" tail -n 11 ${dump_file} >>${output_file} echo "转储完成保存在 ${output_file}"