Script de bash - partes de chomp fora de uma linha

1

Eu tenho um arquivo de dados (veja o exemplo de três linhas abaixo), separado por tubos.

O que eu quero fazer é "cortar" os campos e colocá-los em variáveis. Eles são de comprimentos pré-definidos. Eu quero transformar o arquivo em um script SQL como por:

Entrada:

|          416|CAWNBORE LIMITED                                                                                              |CAWNBORE                 |     8|            0|     0|00.00     |            0|            0|********NO ADDRESS DETAILS*******                 |********NO ADDRESS DETAILS*******                 |********NO ADDRESS DETAILS*******                 |********NO ADDRESS DETAILS*******                 |            0|            0|            0|            0|            0|
|          431|MAIN HOLDINGS LIMITED                                                                                         |MAINHOLDINGSCHA          |     8|            0|     0|00.00     |            0|            0|********NO ADDRESS DETAILS*******                 |********NO ADDRESS DETAILS*******                 |********NO ADDRESS DETAILS*******                 |********NO ADDRESS DETAILS*******                 |            0|     19650509|            0|            0|            0|
|          432|DUBLIN NORTH CITY MILLING COMPANY LIMITED                                                                     |DUBLINNORTHCITY          |     8|            0|     1|00.00     |     18750125|     19830124|113 PHIBSBORO ROAD                                |DUBLIN                                            |                                                  |                                                  |       216410|     19901106|            0|     20030124|            0|

Basicamente, retire os canais - separe os dados com vírgulas e insira a string SQL INSERT INTO .... VALUES (data_in_here separada por vírgula);

Saída desejada:

INSERT INTO tbcrocompany (id_company, nm_company, id_keyword, cd_status, dt_company_status, cd_type, cd_principle_obj, dt_register, dt_last_ar, ad_line_1, ad_line_2, ad_line_3, ad_line_4, cd_town_number, dt_dissolved, dt_bond_expiry, dt_next_ar, dt_last_accounts) VALUES (416,'CAWNBORE LI|MITED','CAWNBORE',8,0,0, '00.00', 0, 0, '********NO ADDRESS DETAILS*******', '********NO ADDRESS DETAILS*******', '********NO ADDRESS DETAILS*******', '********NO ADDRESS DETAILS*******', 0, 0, 0, 0, 0);
INSERT INTO tbcrocompany (id_company, nm_company, id_keyword, cd_status, dt_company_status, cd_type, cd_principle_obj, dt_register, dt_last_ar, ad_line_1, ad_line_2, ad_line_3, ad_line_4, cd_town_number, dt_dissolved, dt_bond_expiry, dt_next_ar, dt_last_accounts) VALUES (431,'MAIN HOLDIN|GS LIMITED','MAINHOLDINGSCHA',8,0,0, '00.00', 0, 0, '********NO ADDRESS DETAILS*******', '********NO ADDRESS DETAILS*******', '********NO ADDRESS DETAILS*******', '********NO ADDRESS DETAILS*******', 0, 19650509, 0, 0, 0);
INSERT INTO tbcrocompany (id_company, nm_company, id_keyword, cd_status, dt_company_status, cd_type, cd_principle_obj, dt_register, dt_last_ar, ad_line_1, ad_line_2, ad_line_3, ad_line_4, cd_town_number, dt_dissolved, dt_bond_expiry, dt_next_ar, dt_last_accounts) VALUES (432,'DUBLIN NORTH CITY MILLING COMPANY LIMITED','DUBLINNORTHCITY',8,0,1, '00.00', 18750125, 19830124, '113 PHIBSBORO ROAD', 'DUBLIN', '', '', 216410, 19901106, 0, 20030124, 0);
    
por Vérace 24.03.2016 / 21:52

2 respostas

3

Supondo que seus dados estão em um arquivo data , isso deve funcionar para uma entrada razoável (por exemplo, você não tem | ou caracteres de nova linha em seus dados):

sed -e 's/^ *| *//' -e 's/ *$//' -e 's/ *| */|/g' data |
    while IFS='|' read -r f1 f2 f3 f4 f5 f6
    do
        # INSERT INTO mt (F1, F2, F3, F4, F5, F6) VALUES ( 16524,01,'10/17/2012','3930621977','XXNPUES        ', 'S1');
        echo "INSERT INTO mt (F1, F2, F3, F4, F5, F6) VALUES ($f1,$f2,'$f3','$f4','$f5','$f6');"
    done

A primeira linha apara espaços iniciais e finais das entradas de dados e descarta o | inicial, de forma que | 416|CABlah |Somewhere else | se torne 416|CABlah|Somewhere else| . As expressões podem ser modificadas ou removidas inteiramente se isso não for apropriado para seu caso de uso.

    
por 24.03.2016 / 22:50
0

Aqui está um script perl que faz o trabalho. Ele pode ser facilmente modificado para funcionar em outras tabelas apenas alterando a string $tablename , bem como as matrizes @fields e @types .

Esse script seria significativamente mais curto se o arquivo de entrada tivesse os nomes de campo na primeira linha, como é comum em muitos arquivos CSV. A matriz @types ainda precisaria ser criada manualmente, caso contrário, não há como o script saber quais campos são strings e quais são números. OTOH, se o arquivo de entrada tivesse essa primeira linha, o script poderia ser escrito para usar o módulo Text::CSV ou DBD::CSV .

Obtém sua entrada de qualquer / todos os nomes de arquivos especificados na linha de comando e / ou de stdin.

#! /usr/bin/perl

use strict;

my $tablename = 'tbcrocompany';

# field names array.  This will be used later to construct
# the %fields hash, and to print the field names in the 
# INSERT statement.
my @fields = qw(id_company nm_company id_keyword cd_status
    dt_company_status cd_type cd_principle_obj dt_register
    dt_last_ar ad_line_1 ad_line_2 ad_line_3 ad_line_4
    cd_town_number dt_dissolved dt_bond_expiry dt_next_ar
    dt_last_accounts);

# fields can be string (s) or number (n)
my @types = qw(n s s n n n n n n s s s s n n n n n);

# initialise the field types hash.
my %types=();
my $fieldnum=0;
foreach my $f (@fields) {
    $types{$f} = $types[$fieldnum++];
}

while (<>) {
    my %fields=();

    # remove leading '|' from line
    s/^\|//;

    # split each input line by '|'
    my @row = split(/\|/);

    # add each element of @row to the appropriate record in the %fields hash
    my $fieldnum=0;
    foreach my $f (@fields) {
        $fields{$f} = $row[$fieldnum++];
        # strip leading and trailing spaces from field value
        $fields{$f} =~ s/^\s*|\s*$//g;
    }

    # construct the VALUES( ... ) section of the output line,
    # with quotes for string values but not for numbers.
    my @values = ();
    foreach my $f (@fields) {
        if ($types{$f} eq 's') {
            push @values, "'$fields{$f}'"
        } else {
            push @values, $fields{$f}
        };
    }

    # and, finally, output the line.
    print "INSERT INTO $tablename (", join(', ',@fields),
          ") VALUES (", join(", ",@values), ";\n";
    }
    
por 25.03.2016 / 03:25