删除转储文件中 SQL 插入命令的两列

删除转储文件中 SQL 插入命令的两列

我有一个包含多个插入命令的 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

相关内容