두 개의 커다란 .csv 파일을 가지고 있는데 하나는 약 8GB이고 다른 하나는 3.4GB의 파일 크기입니다. 그 .csv 파일 안의 각 줄에서 몇 가지 값만 원한다. 데이터를 수정하고 새 파일에 복사하는 데 많은 시간이 걸립니다.큰 파일을 perl 스크립트를 사용하여 한 줄씩 수정
누구든지 코드 수정에 도움을 줄 수 있습니까? 수정은 적절한 시간 내에 완료됩니다.
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
require "$ENV{'SAI_HOME'}/bin/utils/Logging.pl";
require "$ENV{'SAI_HOME'}/bin/utils/Utilities.pl";
my $date1 = `date '+%d-%m-%Y_%H-%M-%Ss'`;
chomp($date1);
our $LOGPATH = "$ENV{'SAI_HOME'}/logs/SP6migrationcsv_$date1.log";
my $status = 0;
log_info("Refer $LOGPATH log file for more information");
my $csv = Text::CSV->new({ binary => 1, eol => $/, sep_char => ',' });
my $file1 = $ARGV[0] or die "Please provide Subscriber and Subscription CSV files on the command line\n";
my $file2 = $ARGV[1] or die "Please provide Subscriber and Subscription CSV files on the command line\n";
my $subscriberFile = "";
my $subscriptionFile = "";
if ((grep /SUBSCRIBER/i, $file1) && (grep /SUBSCRIPTION/i, $file2)) {
$subscriberFile = $file1;
$subscriptionFile = $file2;
} elsif ((grep /SUBSCRIBER/i, $file2) && (grep /SUBSCRIPTION/i, $file1)) {
$subscriptionFile = $file1;
$subscriberFile = $file2;
} else {
log_error("Invalid CSV files input");
exit -1;
}
my $SP6DIR = `dirname $0`;
chomp $SP6DIR;
$SP6DIR = "${SP6DIR}/SP6";
`mkdir -p $SP6DIR` or checkExit($?, "Unable to carete $SP6DIR directory");
my $newSubscriberFile = "Subscriber.csv";
my $newSubscriptionFile = "Subscription.csv";
my $subscriptionimsifile = "$SP6DIR/.IMSI_$newSubscriptionFile";
my $subscriberimsifile = "$SP6DIR/.IMSI_$newSubscriberFile";
$newSubscriberFile = "${SP6DIR}/$newSubscriberFile";
$newSubscriptionFile = "${SP6DIR}/$newSubscriptionFile";
`dos2unix $subscriptionFile $subscriberFile 2>/dev/null`
or checkExit($?, "Unable to perform dos2unix on input files");
`cut -d "," -f3 $subscriptionFile > $subscriptionimsifile`
or checkExit($?, "Failed to get IMSI details from $subscriptionFile");
`cut -d "," -f1 $subscriberFile > $subscriberimsifile`
or checkExit($?, "Failed to get IMSI details from $subscriberFile");
my $isSubscriptionHeaderPresesnt = "false";
my $isSubscriberHeaderPresesnt = "false";
$status = system("head -1 $subscriptionimsifile | grep 'IMSI' >>/dev/null");
if ($status == 0) {
$isSubscriptionHeaderPresesnt = "true";
}
$status = system("head -1 $subscriberimsifile | grep 'IMSI' >>/dev/null");
if ($status == 0) {
$isSubscriberHeaderPresesnt = "true";
}
open(my $subscriptionData, '<:encoding(utf8)', $subscriptionFile)
or die "Could not open '$subscriptionFile' $!\n";
open(NEWSUBSCRIBERDATA, "> $newSubscriberFile") or die "Could not open '$newSubscriberFile' $!\n";
open(NEWSUBSCRIPTIONDATA, "> $newSubscriptionFile") or die "Could not open '$newSubscriptionFile' $!\n";
if ("$isSubscriptionHeaderPresesnt" eq "true") {
my $subscriptionHeader = <$subscriptionData>;
if ($csv->parse($subscriptionHeader)) {
my @subscriptionHeaderFields = $csv->fields();
print NEWSUBSCRIPTIONDATA "\"$subscriptionHeaderFields[0]\",\"$subscriptionHeaderFields[2]\",\"$subscriptionHeaderFields[4]\",\"$subscriptionHeaderFields[5]\",\"$subscriptionHeaderFields[6]\",\"$subscriptionHeaderFields[8]\",\"$subscriptionHeaderFields[13]\",\"$subscriptionHeaderFields[14]\",\"$subscriptionHeaderFields[15]\",\"$subscriptionHeaderFields[16]\",\"$subscriptionHeaderFields[17]\",\"$subscriptionHeaderFields[18]\",\"$subscriptionHeaderFields[25]\",\"$subscriptionHeaderFields[26]\",\"$subscriptionHeaderFields[27]\"\n";
print NEWSUBSCRIBERDATA "\"IMSI\",\"IMEI\",\"MSISDN\",\"$subscriptionHeaderFields[21]\",\"$subscriptionHeaderFields[22]\",\"$subscriptionHeaderFields[12]\",\"$subscriptionHeaderFields[9]\",\"$subscriptionHeaderFields[1]\",\"$subscriptionHeaderFields[0]\"\n";
} else {
log_error("Line could not be parsed: $subscriptionHeader\n");
exit 1;
}
} else {
log_only("No header info in subscription file");
}
if ("$isSubscriptionHeaderPresesnt" eq "false" && "$isSubscriberHeaderPresesnt" eq "true") {
print NEWSUBSCRIBERDATA "\"IMSI\",\"IMEI\",\"MSISDN\",\"CUSTOMER_SEGMENTATION\",\"CUST_SUBCATEGORY\",\"SUBS_TYPE\",\"SUBSCRIPTION_PLAN\",\"CONTRACT_IDREF\",\"SUBSCRIPTION_IDREF\"\n";
} else {
log_only("No header info in subscriber file");
}
my $subscriberHeader = "";
my @subscriptionFields = {};
my @subscriberFields = {};
while (my $eachSubscriptionLine = <$subscriptionData>) {
chomp $eachSubscriptionLine;
if ($csv->parse($eachSubscriptionLine)) {
@subscriptionFields = $csv->fields();
$status = system("grep \"^[\\\"]*${subscriptionFields[2]}[\\\"]*\\\$\" $subscriberimsifile >> /dev/null");
if ($status == 0) {
my $lastMatchedSubscriberdata = `grep "^[\\\"]*${subscriptionFields[2]}[\\\"]*," $subscriberFile | tail -1`;
chomp $lastMatchedSubscriberdata;
if ($csv->parse($lastMatchedSubscriberdata)) {
@subscriberFields = $csv->fields();
if ("${subscriberFields[0]}" eq "${subscriptionFields[2]}") {
#log_only("Updating \"@subscriberFields\" subscriber details from subscription data");
print NEWSUBSCRIBERDATA "\"$subscriberFields[0]\",\"$subscriberFields[1]\",\"$subscriptionFields[2]\",\"$subscriptionFields[21]\",\"$subscriptionFields[22]\",\"$subscriptionFields[12]\",\"$subscriptionFields[9]\",\"$subscriptionFields[1]\",\"$subscriptionFields[0]\"\n";
} else {
log_error("Unable to process @subscriberFields record");
exit -1;
}
} else {
log_error("Line could not be parsed: $lastMatchedSubscriberdata\n");
exit 1;
}
} else {
log_only("Adding new subscriber details from subscription : \"@subscriptionFields\"");
print NEWSUBSCRIBERDATA "\"$subscriptionFields[2]\",,\"$subscriptionFields[3]\",\"$subscriptionFields[21]\",\"$subscriptionFields[22]\",\"$subscriptionFields[12]\",\"$subscriptionFields[9]\",\"$subscriptionFields[1]\",\"$subscriptionFields[0]\"\n";
}
print NEWSUBSCRIPTIONDATA "\"$subscriptionFields[0]\",\"$subscriptionFields[2]\",\"$subscriptionFields[4]\",\"$subscriptionFields[5]\",\"$subscriptionFields[6]\",\"$subscriptionFields[8]\",\"$subscriptionFields[13]\",\"$subscriptionFields[14]\",\"$subscriptionFields[15]\",\"$subscriptionFields[16]\",\"$subscriptionFields[17]\",\"$subscriptionFields[18]\",\"$subscriptionFields[25]\",\"$subscriptionFields[26]\",\"$subscriptionFields[27]\"\n";
} else {
log_error("Line could not be parsed: $eachSubscriptionLine\n");
exit 1;
}
}
close(NEWSUBSCRIPTIONDATA);
open(my $subscriberData, '<:encoding(utf8)', $subscriberFile) || die "Could not open '$subscriberFile' $!\n";
if ("$isSubscriberHeaderPresesnt" eq "true") {
$subscriberHeader = <$subscriberData>;
}
while (my $eachSubscriberLine = <$subscriberData>) {
chomp $eachSubscriberLine;
if ($csv->parse($eachSubscriberLine)) {
@subscriberFields = $csv->fields();
$status = system("grep \"^[\\\"]*${subscriberFields[0]}[\\\"]*\\\$\" $subscriptionimsifile >>/dev/null");
if ($status != 0) {
log_only(
"Adding back subscriber details, because unable to get IMSI details from subscription file : \"@subscriberFields\""
);
print NEWSUBSCRIBERDATA "\"$subscriberFields[0]\",\"$subscriberFields[1]\",\"$subscriberFields[2]\",\"$subscriberFields[6]\",,\"$subscriberFields[7]\",,,\n";
}
} else {
log_error("Line could not be parsed: $eachSubscriberLine\n");
exit 1;
}
}
close(NEWSUBSCRIBERDATA);
`sed -i -e '1 s|SUBSCRIPTION_ID|SUBSCRIPTION_IDREF|g' -e '1 s|SUBS_CATEGORY|SUBSCRIPTION_PLAN|g' -e '1 s|SUBS_STATE|SUBS_TYPE|g' -e '1 s|CUST_CATEGORY|CUSTOMER_SEGMENTATION|g' $newSubscriberFile`
or checkExit($?, "Unable to update header info in subscriber fi le");
@ jm666 그래도 성능에 대해 불평해서는 안됩니다. csv가 의무적 인 경우 가져 오기/내보내기 데이터베이스 형식으로 만 사용할 수 있지만 자주 업데이트하는 데는 사용할 수 없습니다. –
@mpapec thats 's fair :) – jm666
아마도 여러분은 긴 코드를 분석해야 할 것입니다. 여기서 여러분은 여러 번 외부 명령을 호출 할 것입니다. 할 수있는 최선의 방법은 코드 부분에서 가장 많은 시간이 걸리는 부분을 찾아 몇 줄의 코드로 문제를 줄이고 몇 가지 샘플 입력과 원하는 출력 샘플을 제공하는 것입니다. 없이는 더 이상 뭔가를 추천하지 않고, 8GB file_에 3 개의 외부 프로세스를 호출하고 연속적으로 행을 처리합니다 ._ 그리고 그러한 일반적인 일 ... 그리고 [ask]를 읽어주십시오. – jm666