Perl脚本修改文件 [英] Perl script to modify file
问题描述
我有需要与CVS文件进行比较的Oracle文件,但是问题是,作为差异的一部分,我想忽略很多第一行.我想运行一个脚本来打开每个文件,并以最终输出将'CREATE OR REPLACE PACKAGE "TRON"."SOME_PACKAGE" IS'
替换为'CREATE OR REPLACE PACKAGE SOME_PACKAGE IS'
的方式替换文件内容.我遇到的问题是该语句可以跨越多行,因此我必须考虑类似'CREATE OR REPLACE "TRON"."SOME_PACKAGE"
.
IS'
我的方法(因为这是Jenkins作业的一部分),是遍历工作区中的所有文件,修改满足此条件的任何文件.然后,我可以使用使用File::Compare
和Text::Diff::Table
的现有Perl脚本.
我一直在使用 Zaid的解决方案进行测试,但收效甚微它仍然没有处理命令字符串跨越多行的情况. (我的更改):
use strict;
use warnings;
use Tie::File;
use Data::Dumper;
my @array;
tie @array, 'Tie::File', 'c:\cb_k_check_recon_mma.sps' or die "Unable to tie file";
my %unwanted = map { $_ => 1 }
map { $_-1..$_-4, $_, $_+2 .. $_+4 }
grep { $array[$_] =~ /^CREATE.*[IS|AS]$/ }
0 .. $#array ;
print Dumper \%unwanted;
@array = map { $array[$_] } grep { ! $unwanted{$_} } 0 .. $#array;
print Dumper \@array;
untie @array;
如果文本可以跨越多行,则要使单个正则表达式正常工作,您需要将文件读取为字符串,而不是逐行读取.
>
perl -0777 -pi.bak -e 's/CREATE\s+OR\s+REPLACE\s+PACKAGE\s+"TRON"\."SOME_PACKAGE"\s+IS/CREATE OR REPLACE PACKAGE SOME_PACKAGE IS/g' /path/*.pl
-0777
开关告诉perl压缩文件,因此regex将仅运行一次.因此,我添加了全局/g
修饰符,以防每个文件需要多个替换.
如您所见,我使用\s+
而不是空格来匹配可能随机插入的换行符.简而言之,-pi
意味着对目标文件执行就地编辑,而-i
之后的.bak
意味着保存具有该扩展名的备份.建议保存备份,但不是必需的(在Windows上除外).
I have Oracle files that I need to compare to CVS files, but the problem is that there are many files that I want to ignore the first line(s) as part of the diff. I want to run a script that opens each file, and replaces the file contents in such a way that the final output is replacing 'CREATE OR REPLACE PACKAGE "TRON"."SOME_PACKAGE" IS'
with 'CREATE OR REPLACE PACKAGE SOME_PACKAGE IS'
. The problem I am having is that the statement can span several lines, so I have to consider a situation like 'CREATE OR REPLACE "TRON"."SOME_PACKAGE"
.
IS'
My approach (since this is part of a Jenkins job), is to loop through all the files in the workspace, modifying any files that meet this criteria. I can then use my existing Perl script that is using File::Compare
and Text::Diff::Table
.
I've been testing with Zaid's solution with little success, since it still is not dealing with scenarios where the command string spans multiple lines. (my changes):
use strict;
use warnings;
use Tie::File;
use Data::Dumper;
my @array;
tie @array, 'Tie::File', 'c:\cb_k_check_recon_mma.sps' or die "Unable to tie file";
my %unwanted = map { $_ => 1 }
map { $_-1..$_-4, $_, $_+2 .. $_+4 }
grep { $array[$_] =~ /^CREATE.*[IS|AS]$/ }
0 .. $#array ;
print Dumper \%unwanted;
@array = map { $array[$_] } grep { ! $unwanted{$_} } 0 .. $#array;
print Dumper \@array;
untie @array;
If the text can span several lines, for a single regex to work you need to read the file into a string, not line-by-line.
perl -0777 -pi.bak -e 's/CREATE\s+OR\s+REPLACE\s+PACKAGE\s+"TRON"\."SOME_PACKAGE"\s+IS/CREATE OR REPLACE PACKAGE SOME_PACKAGE IS/g' /path/*.pl
The -0777
switch tells perl to slurp the file, so the regex will only be run once. For that reason, I added the global /g
modifier, in case more than one substitution per file is needed.
As you see, I use \s+
instead of space, to match possible randomly inserted newlines. -pi
in short means to perform in-place edit on the target file(s), and .bak
after -i
means to save backups with that extension. It is recommendable to save backups, but not required (except on Windows).
这篇关于Perl脚本修改文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!