我有一个包含多个插入命令的 SQL 转储文件。我想删除,通过sed或者grep(或者甚至是另一个简单的巴什技巧)、子句中的特定列及其等效数据VALUES
。因此:
INSERT INTO "capt" ("fid_c1","id","fid_capt","mslink","capt", ...) VALUES ('0','0','24','189','CAP.FU1', ...);
sed 或 grep 应删除该"mslink"
列及其对应的值"189"
- 两者都位于第 4个位置。值得注意我不知道不需要的列的原始位置因此,正则表达式必须使用某种内存来删除第 n个查询的值是n的位置"mslink"
。
一个不完整的 sed命令将是这样的:
sed -re 's/INSERT INTO "capt" \((.*,?)*"mslink",?(.*,?)*\) VALUES \((.*,?)+\);/INSERT INTO "capta" (\1\2) VALUES (\3)/' file.sql
答案1
我想不出 Perl 单行代码可以完成这项任务,但这里有一个 Perl 脚本可以满足您的要求。
将 $match 更改为您要搜索的内容。该脚本循环遍历文件并将结果文件打印到标准输出。将结果通过管道传输到文件中,您就会得到更改。我本来想对代码进行更多注释。对于那个很抱歉。
该脚本依赖于“VALUES”关键字,数据位于括号中并以逗号分隔。否则它可能会失败。
如果代码保存为“sql_parser.pl”则运行命令%> perl sql_parser.pl [文件]
#!/usr/bin/perl
#
use strict;
sub usage
{
print "usage: sql_parser.pl [file]\n";
}
# load the input file
sub load
{
my $file = shift;
open my $in, "<", $file or die "unable to open $file as input $!";
my @data = <$in>;
close $in;
foreach (@data) { chomp; s/\cM//g; }
return @data;
}
# what to search for
# could supply this parameter on the command line too
# my $match = shift;
my $match = 'mslink';
# get the file to process on the command line
my $file = shift;
{
# load the data
my @lines = &load($file);
#print "$_\n" foreach (@lines);
# loop through the data in the file
foreach (@lines)
{
# match the line of text
my @f = m/(.*?\() (.*?) (\)\s+?VALUES\s+?\() (.*?) (\).*?$)/x;
if (@f)
{
my @cmds = split /,/, $f[1];
my @nums = split /,/, $f[3];
my $matched = 0;
for ( my $i = 0; $i < @cmds; ++$i )
{
if ( $cmds[$i] =~ /$match/ )
{
#print "$cmds[$i]\n";
undef $cmds[$i];
undef $nums[$i];
$matched = 1;
last;
}
}
( $f[1] = join ',', @cmds ) =~ s/\,\,/,/;
( $f[3] = join ',', @nums ) =~ s/\,\,/,/;
if ($matched)
{
$_ = join ' ', @f;
}
}
}
print "$_\n" foreach (@lines);
}
我对这些数据运行了这个脚本:
INSERT INTO "capt" ("fid_c1","id","fid_capt","mslink","capt", ...) VALUES ('0','0','24','189','CAP.FU1', ...);
$ perl sql_parser.pl test.dat 输出如下:
INSERT INTO "capt" ( "fid_c1","id","fid_capt","capt", ... ) VALUES ('0','0','24','CAP.FU1', ... );
捕获输出: $ perl sql_parser.pl test.dat > capture.txt