파이프로 구분된 데이터 파일이 있습니다(아래 세 줄의 예 참조).
내가 원하는 것은 필드를 "제거"하여 변수에 넣는 것뿐입니다. 미리 정의된 길이가 있습니다. 파일을 다음과 같은 SQL 스크립트로 변환하고 싶습니다.
입력하다:
| 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|
기본적으로 파이프를 제거합니다. 데이터를 쉼표로 구분하고 SQL 문자열 INSERT INTO .... VALUES( data_in_here comma Split );
원하는 출력:
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);
답변1
데이터가 파일에 있다고 가정하면 data
작동합니다.합리적인입력(예: 데이터에 줄 바꿈 없음 |
):
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
첫 번째 줄은 데이터 입력에서 선행 및 후행 공백을 제거하고 초기 공백을 삭제하여 |
가 | 416|CABlah |Somewhere else |
됩니다 416|CABlah|Somewhere else|
. 사용 사례에 맞지 않는 경우 표현식을 완전히 수정하거나 제거할 수 있습니다.
답변2
perl
다음은 작업을 수행하는 스크립트 입니다 . $tablename
문자열과 배열 만 변경하면 @fields
다른 테이블과 함께 작동하도록 쉽게 수정할 수 있습니다 @types
.
입력 파일의 첫 번째 줄에 필드 이름(많은 CSV 파일에서 일반적임)이 포함되어 있으면 이 스크립트가 상당히 단축됩니다. 배열 @types
은 여전히 수동으로 생성되어야 합니다. 그렇지 않으면 스크립트는 어떤 필드가 문자열이고 어떤 필드가 숫자인지 알 수 없습니다. OTOH, 입력 파일에 이와 같은 첫 번째 줄이 있으면 Text::CSV
또는 DBD::CSV
모듈을 사용하도록 스크립트를 작성할 수 있습니다.
명령줄에 지정된 모든 파일 이름 및/또는 표준 입력에서 입력을 받습니다.
#! /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";
}