Remover duas colunas de um comando de inserção SQL em um arquivo de despejo

0

Eu tenho um arquivo de despejo SQL com vários comandos de inserção. Gostaria de remover, por meio do sed ou do grep (ou até mesmo outro truque simples bash ), uma coluna específica e seus dados equivalentes na% cláusulaVALUES. Assim:

INSERT INTO "capt" ("fid_c1","id","fid_capt","mslink","capt", ...) VALUES ('0','0','24','189','CAP.FU1', ...);

Sed ou grep devem remover a coluna "mslink" e seu valor correspondente "189" - ambos estão na posição 4 th . Vale a pena notar eu não sei a posição original da coluna indesejada e, assim, a expressão regular deve usar algum tipo de memória para soltar o n th valor da consulta, sendo n a posição do "mslink" .

Um comando incompleto sed seria assim:

sed -re 's/INSERT INTO "capt" \((.*,?)*"mslink",?(.*,?)*\) VALUES \((.*,?)+\);/INSERT INTO "capta" () VALUES ()/' file.sql
    
por Juliano B. Nequirito 12.12.2016 / 18:30

1 resposta

0

Eu não conseguia pensar em perl one-liner para a tarefa, mas aqui está um script perl que fará o que você quiser.

Altere $ match para o que você deseja pesquisar. O script percorre o arquivo e imprime o arquivo resultante na saída padrão. Canalize esse resultado para um arquivo e você terá sua alteração. Eu quis comentar o código mais. Desculpe por isso.

O script depende da palavra-chave "VALUES", os dados estão entre parênteses e são delimitados por vírgulas. Provavelmente falhará de outra forma.

Comando para executar se o código for salvo como 'sql_parser.pl' % > perl sql_parser.pl [arquivo]

#!/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);
}

Eu executei este script nesses dados:

INSERT INTO "capt" ("fid_c1","id","fid_capt","mslink","capt", ...) VALUES ('0','0','24','189','CAP.FU1', ...);

$ perl sql_parser.pl test.dat A saída está abaixo:

INSERT INTO "capt" ( "fid_c1","id","fid_capt","capt", ... ) VALUES ('0','0','24','CAP.FU1', ... );

Para capturar a saída: $ perl sql_parser.pl test.dat > capture.txt

    
por 14.12.2016 / 00:16