3
私はまだOracleファイルのクリーンアップに取り組んでいます。ファイル内の関数/プロシージャ/パッケージ名の前にOracleスキーマ名が付加されているファイルの文字列を置き換える必要があります。関数/プロシージャ/パッケージ名は二重引用符で囲まれています。定義が修正されると、実際のコードの残りの部分とともに、ファイルに修正を書き戻します。アンカーワード間の文字列をキャプチャするPerlの正規表現
私は単純な宣言(入出力パラメータなし)を置き換えるように書かれたコードを持っています今、私は正規表現を操作しようとしています(注:この記事は続きですthis question)クリーンアップ:
置き換えます
CREATE OR REPLACE FUNCTION "TRON2000"."DC_F_DUMP_CSV_MMA" (
p_trailing_separator IN BOOLEAN DEFAULT FALSE,
p_max_linesize IN NUMBER DEFAULT 32000,
p_mode IN VARCHAR2 DEFAULT 'w'
)
RETURN NUMBER
IS
CREATE OR REPLACE FUNCTION DC_F_DUMP_CSV_MMA (
p_trailing_separator IN BOOLEAN DEFAULT FALSE,
p_max_linesize IN NUMBER DEFAULT 32000,
p_mode IN VARCHAR2 DEFAULT 'w'
)
RETURN NUMBER
IS
に私はドを分離するために、次の正規表現を使用しようとしています私はスキーマ名を削除した後の再構築のために/関数/プロシージャ/パッケージの名前を二重引用符で囲まないように修正しました。私は、バッファにそれぞれを得るに苦労しています - ここではそれ自身のバッファにすべての中間の入力/出力をつかむために私の最新の試みです:
\b(CREATE\sOR\sREPLACE\s(PACKAGE|PACKAGE\sBODY|PROCEDURE|FUNCTION))(?:\W+\w+){1,100}?\W+(RETURN)\s*(\W+\w+)\s(AS|IS)\b
どれ/すべてのヘルプは大歓迎です!
これは私が修正されたファイルの書き込み/評価するために、今使っているスクリプトです:
#!/usr/bin/perl
use strict;
use warnings;
use File::Find;
use Data::Dumper;
# utility to clean strings
sub trim($) {
my $string = shift;
$string = "" if !defined($string);
$string =~ s/^\s+//;
$string =~ s/\s+$//;
# aggressive removal of blank lines
$string =~ s/\n+/\n/g;
return $string;
}
sub cleanup_packages {
my $file = shift;
my $tmp = $file . ".tmp";
my $package_name;
open(OLD, "< $file") or die "open $file: $!";
open(NEW, "> $tmp") or die "open $tmp: $!";
while (my $line = <OLD>) {
# look for the first line of the file to contain a CREATE OR REPLACE STATEMENT
if ($line =~
m/^(CREATE\sOR\sREPLACE)\s*(PACKAGE|PACKAGE\sBODY)?\s(.+)\s(AS|IS)?/i
)
{
# look ahead to next line, in case the AS/IS is next
my $nextline = <OLD>;
# from the above IF clause, the package name is in buffer 3
$package_name = $3;
# if the package name and the AS/IS is on the same line, and
# the package name is quoted/prepended by the TRON2000 schema name
if ($package_name =~ m/"TRON2000"\."(\w+)"(\s*|\S*)(AS|IS)/i) {
# grab just the name and the AS/IS parts
$package_name =~ s/"TRON2000"\."(\w+)"(\s*|\S*)(AS|IS)/$1 $2/i;
trim($package_name);
}
elsif ( ($package_name =~ m/"TRON2000"\."(\w+)"/i)
&& ($nextline =~ m/(AS|IS)/))
{
# if the AS/IS was on the next line from the name, put them together on one line
$package_name =~ s/"TRON2000"\."(\w+)"(\s*|\S*)/$1/i;
$package_name = trim($package_name) . ' ' . trim($nextline);
trim($package_name); # remove trailing carriage return
}
# now put the line back together
$line =~
s/^(CREATE\sOR\sREPLACE)\s*(PACKAGE|PACKAGE\sBODY|FUNCTION|PROCEDURE)?\s(.+)\s(AS|IS)?/$1 $2 $package_name/ig;
# and print it to the file
print NEW "$line\n";
}
else {
# just a normal line - print it to the temp file
print NEW $line or die "print $tmp: $!";
}
}
# close up the files
close(OLD) or die "close $file: $!";
close(NEW) or die "close $tmp: $!";
# rename the temp file as the original file name
unlink($file) or die "unlink $file: $!";
rename($tmp, $file) or die "can't rename $tmp to $file: $!";
}
# find and clean up oracle files
sub eachFile {
my $ext;
my $filename = $_;
my $fullpath = $File::Find::name;
if (-f $filename) {
($ext) = $filename =~ /(\.[^.]+)$/;
}
else {
# ignore non files
return;
}
if ($ext =~ /(\.spp|\.sps|\.spb|\.sf|\.sp)/i) {
print "package: $filename\n";
cleanup_packages($fullpath);
}
else {
print "$filename not specified for processing!\n";
}
}
MAIN:
{
my (@files, $file);
my $dir = 'C:/1_atest';
# grab all the files for cleanup
find(\&eachFile, "$dir/");
#open and evaluate each
foreach $file (@files)
{
# skip . and ..
next if ($file =~ /^\.$/);
next if ($file =~ /^\.\.$/);
cleanup_file($file);
};
}
素晴らしい@tuxuday!非常に効率的で、はるかに少ない複雑さ - ありがとう!私は現在、私が掃除が必要な文字列が 'TRON2000.DC_F_DUMP_CSV_MMA'から' DC_F_DUMP_CSV_MMA'(スキーマ名は存在しますが、二重引用符はありません)の私の他のケースに対して少し修正しようとします。ありがとうございました! –