我正在尝试编写一个perl脚本,用一些其他行替换几行文本,我是一个perl新手,感谢任何帮助。
需要更换
'ENTITLEMENT_EVS_V',
NULL,
NULL,
使用:
'ENTITLEMENT_EVS_V',
ENTITLEMENT_CATEGORY_CODE,
6,
我无法这样做,尤其是正则表达式部分。我尝试了很多东西,但脚本目前代表:
#!/usr/bin/env perl
my ($lopen_fh, $lwrite_fh);
# my $l_reg_evs = qq{
#'ENTITLEMENT_EVS_V',
#NULL,
#NULL,
#};
my $l_reg_evs = qr/(\'ENTITLEMENT_EVS_V\',
NULL,
NULL,
)/;
my $l_evs=qq{
'ENTITLEMENT_EVS_V',
ENTITLEMENT_CATEGORY_CODE,
6,
};
open ($lopen_fh, '<', "/home/cbdev2/imp/dev/src/deli/entfreeunits/config/entfreeunits/stubs/DirectVariables_evEntlCategory.exp") or die $!;
open ($lwrite_fh, '>', "/home/cbdev2/imp/dev/src/deli/entfreeunits/config/entfreeunits/stubs/DirectVariables_evEntlCategory.new.exp") or die $!;
while(<$lopen_fh>) {
$_ =~ s/$l_reg_evs/$l_evs/m;
print $lwrite_fh $_;
}
close $lopen_fh;
close $lwrite_fh;
答案 0 :(得分:2)
我不太清楚你想要做什么,但我试图将你的问题的本质提炼成一个自包含的脚本。在一个真正的程序中,你将阅读并解析变量名称到类别和代码的映射,但在这里,我只是从字符串中读取。这样做的目的是表明可以在不丢弃文件的情况下完成任务。
#!/usr/bin/env perl
use strict;
use warnings;
my $entitlement_map_file = <<EOF_MAP_FILE;
'ENTITLEMENT_EVS_V'
ENTITLEMENT_CATEGORY_CODE
6
EOF_MAP_FILE
my $entitlement_input_file = <<EOF_INPUT_FILE;
'ENTITLEMENT_EVS_V',
NULL,
NULL,
EOF_INPUT_FILE
# read and parse the file containing mapping of
# variables to category names and codes
open my $map_fh, '<', \$entitlement_map_file
or die $!;
my %map;
while (my $var = <$map_fh>) {
chomp $var;
chomp( my $mnemonic = <$map_fh> );
chomp( my $code = <$map_fh>);
@{ $map{$var} }{qw(mnemonic code)} = ($mnemonic, $code);
}
close $map_fh;
# read the input file, look up variable name in the map
# if there, follow with category name and code
# skip two lines from input, continue where you left off
open my $in, '<', \$entitlement_input_file
or die $!;
while (my $var = <$in>) {
$var =~ s/,\s+\z//;
next unless exists $map{ $var };
for (1 .. 2) {
die unless <$in> =~ /^NULL/;
}
print join(",\n", $var, @{ $map{$var} }{qw(mnemonic code)}), "\n";
}
close $in;
输出:
'ENTITLEMENT_EVS_V', ENTITLEMENT_CATEGORY_CODE, 6
概括这是留给读者的练习。
答案 1 :(得分:1)
我想我会写这样的东西。它期望输入文件的路径作为命令行上的参数,并将结果打印到STDOUT
它要求以下所有内容为真
要搜索的块的第一行和要替换的块始终相同
要搜索的块中的行数和要替换的块始终相同
输入文件始终包含要搜索一次的块的第一行
无需检查块中第一行之后文件中的行是NULL,
,只需找到第一行并删除以下行就足够了
它的工作原理是读取输入文件并将其复制到STDOUT。如果它遇到包含替换块的第一行的行,则它将读取并丢弃行,直到读取的行数等于替换块的大小。然后将替换块中的文本打印到STDOUT并继续复制
use strict;
use warnings 'all';
no warnings 'qw'; # avoid warning about commas in qw//
my @replacement = qw/
'ENTITLEMENT_EVS_V',
ENTITLEMENT_CATEGORY_CODE,
6,
/;
open my $fh, '<', $ARGV[0];
while ( <$fh> ) {
if ( /$replacement[0]/ ) {
<$fh> for 1 .. $#replacement;
print "$_\n" for @replacement;
}
else {
print;
}
}
这适用于我创建的一些示例数据,但我无法知道上面列出的规定是否适用于您的实际数据。如果需要调整,我相信你会告诉我
答案 2 :(得分:-1)
这就是我的所作所为:
#!/usr/bin/env perl
my ($lopen_fh, $lwrite_fh);
my $l_stub_dir = "/home/cbdev2/imp/dev/src/deli/entfreeunits/config/entfreeunits/stubs";
my $l_stub = "DirectVariables_evEntlCategory.exp";
my $l_filename = "$l_stub_dir/$l_stub";
my $search_evs = 'ENTITLEMENT_EVS_V';
my $search_tre = 'ENTITLEMENT_TRE_V';
my @replacement_evs = qw/
'ENTITLEMENT_EVS_V',
ENTITLEMENT_CATEGORY_CODE,
6,
/;
my @replacement_tre = qw/
'ENTITLEMENT_TRE_V',
ENTITLEMENT_CATEGORY_CODE,
6,
/;
open ($lopen_fh, "<$l_filename") or die $!;
open ($lwrite_fh, ">$l_filename.new") or die $!;
while(<$lopen_fh>) {
if ( /'ENTITLEMENT_EVS_V'/ ) {
<$lopen_fh> for 1 .. $#replacement_evs;
print $lwrite_fh " $_\n" for @replacement_evs;
}
elsif ( /'ENTITLEMENT_TRE_V'/ ) {
<$lopen_fh> for 1 .. $#replacement_tre;
print $lwrite_fh " $_\n" for @replacement_tre;
}
else {
print $lwrite_fh $_;
}
}
close $lopen_fh;
close $lwrite_fh;
unlink($l_filename) or die "Failed to delete $l_filename: $!";
link("$l_filename.new", $l_filename) or die "Failed to copy $l_filename";
unlink("$l_filename.new") or die "Failed to delete $l_filename.new: $!";