Perl脚本修改文件 [英] Perl script to modify file

查看:63
本文介绍了Perl脚本修改文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有需要与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::CompareText::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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆