Shell 如何在perl中替换某个关键字后的行 rerun.txt
a、 b,c,d是$var和1,2$我的代码中的num 我想在cell.txt中搜索$var,并将其对应的下一行区域替换为该文件中类似于$num的区域:1 cell.txt Perl代码 此解决方案将重新运行数据读入哈希%rerun,第一列用于键,第二列用于值。regex模式$re是从一组可能的键构建并编译的 整个cell.txt被读入$cell,以简化处理多行字符串的过程。找到具有以下区域的单元格x{的每次出现:99.99,其中x是%rerun的键之一,随后的99.99被相应哈希元素的值替换 一旦找到并替换了所有内容,新的$cell就会打印到STDOUTShell 如何在perl中替换某个关键字后的行 rerun.txt,shell,perl,Shell,Perl,a、 b,c,d是$var和1,2$我的代码中的num 我想在cell.txt中搜索$var,并将其对应的下一行区域替换为该文件中类似于$num的区域:1 cell.txt Perl代码 此解决方案将重新运行数据读入哈希%rerun,第一列用于键,第二列用于值。regex模式$re是从一组可能的键构建并编译的 整个cell.txt被读入$cell,以简化处理多行字符串的过程。找到具有以下区域的单元格x{的每次出现:99.99,其中x是%rerun的键之一,随后的99.99被相应哈希元素的值替换
我依靠一些比较喜欢正则表达式的人来尝试对可能的输入进行防御,并结合一些步骤。在您的案例中,建议使用最后一个标签作为替代,但我希望OP不会因为我重复了一些人共享的教条而受到伤害。我的版本打印到标准输出,而不是更改原始文件,但应该足够接近。如果是这样的话n有助于打印一些预期输出,但希望我猜对了 在我之前几分钟就完成了,我没有看到他的帖子,这在某种程度上是一种更高级的方法。根据同一个帖子的建议,我删除了对Regexp::Common模块的引用,虽然它与我相关,但我同意这超出了需要
#!/usr/bin/env perl
use Modern::Perl;
open(my $fh, '<', 'rerun.txt') or die "Could not open rerun.txt: $!";
my %new_area;
foreach (<$fh>) {
chomp;
my ($k, $v) = split ',';
die "invalid rerun format" unless ($k =~ /^\w+$/ and $v =~ /^[\d.]+$/);
$new_area{ $k } = $v;
}
open($fh, '<', 'cell.txt') or die "Could not open cell.txt: $!";
my $area_key;
while (<$fh>) {
if ( /^\s* cell \s*\(\s*(\w+)\s*\)\s* { \s*$/x ) {
$area_key = $1;
}
elsif (/^\s* } \s*$/x) {
undef $area_key
}
elsif ( defined($area_key) and /\barea\b/ and
exists $new_area{ $area_key }
) {
s/(area\s*:\s*)[\d.]+/$1$new_area{$area_key}/
}
print;
}
TCL和它有什么关系?我整理了你的Perl代码以便我可以阅读它,但我需要这样做是可耻的。下次你在这里提问时,请更加努力。cell.txt中的每一项都将在rerun.txt中吗?@trenton trama:cell.txt中几乎没有变量需要更改,不是全部。你的尝试在我看来是一个bi老实说,我不喜欢用Perl编写的基本程序,这就是你的答案。首先,为什么不使用strict或使用warning'all'?Borodin,看起来你没有使用Modern::Perl;-为什么我必须了解每个非核心编译模块都做些什么?它是不透明的,对于新手来说不是一个很好的示例。使用strict和use warning'all’已经足够了,并且是不言自明的。为了您自己的目的,请务必使用Modern::Perl,但它不适合用于生产或公共代码。而Regexp::Common是一种过分的用法。[\d.]+除非您尝试验证输入数据,否则没有问题。如果您是,则需要正确处理不匹配,而不是忽略它。OP并不意味着文件格式可能不正确,因此任何巧妙的做法都没有意义。谢谢@mr_ron,我有非常基本的perl版本,我无法安装modern::perl,任何解决方案s、 提前感谢Hanks@Borodin,正如我在上面添加的,我有perl的基本版本,由于BEGIN失败的编译在cell_new.pl第3行被中止,所以我得到了错误。请你能给我建议任何解决方案吗?是的,我只是在学习perl。@Anthonyj看起来你可能使用了一个相当不错的o没有将autodie作为核心模块/pragma包含的Perl的ld版本。corelist autodie显示Perl 5.10.1是第一个这样的版本,您可以检查Perl-v以查看您的版本是否更早。
cell (a) {
area : 2
}
cell (b) {
area : 2.3
}
cell (c) {
area : 2.5
}
cell (d) {
area : 2.7
}
#!usr/bin/perl
use warnings;
use strict;
open( my $fh1, "rerun.txt" ) or die "Couldn't open file file.txt, $!";
my $word = 0;
my $input = "area";
my $num;
my $var;
my $line;
my $a = 0;
my $flag = 0;
my $flag1 = 0;
while ( <$fh1> ) {
( $var, $num ) = split ","; # splitting acc to comma
open( my $fh, "cell.txt" ) or die "Couldn't open file file.txt, $!";
while ( my $line1 = <$fh> ) { # while in the file opened
$line1 =~ s/^\s+//; # removing spaces
my @word = split " ", $line1; # splitting acc to spcaes
foreach $word ( @word ) {
$word =~ s/[(,),]//g; # excluding all brackets (,),{,}
if ( $word eq $var ) {
$flag = 1;
}
if ( $flag == 1 ) {
if ( $word eq "area" ) {
$a = $.; # saving the line number
system( "sed -i '$a s/.*/\t area : $num /' cell.txt" );
goto L1;
}
}
}
}
L1:
close( $fh );
}
close( $fh1 );
use strict;
use warnings 'all';
use autodie;
my %rerun = do {
open my $fh, '<', 'rerun.txt';
map { /[^,\s]/g } <$fh>;
};
my $cell = do {
open my $fh, '<', 'cell.txt';
local $/;
<$fh>;
};
my $re = join '|', sort { length $b <=> length $a } keys %rerun;
$re = qr/$re/;
$cell =~ s/ \b cell \s* \( \s* ( $re ) \s* \) \s* \{ \s* area \s* : \s* \K [\d.]+ /$rerun{$1}/gx;
print $cell;
cell (a) {
area : 1
}
cell (b) {
area : 2
}
cell (c) {
area : 3
}
cell (d) {
area : 4
}
#!/usr/bin/env perl
use Modern::Perl;
open(my $fh, '<', 'rerun.txt') or die "Could not open rerun.txt: $!";
my %new_area;
foreach (<$fh>) {
chomp;
my ($k, $v) = split ',';
die "invalid rerun format" unless ($k =~ /^\w+$/ and $v =~ /^[\d.]+$/);
$new_area{ $k } = $v;
}
open($fh, '<', 'cell.txt') or die "Could not open cell.txt: $!";
my $area_key;
while (<$fh>) {
if ( /^\s* cell \s*\(\s*(\w+)\s*\)\s* { \s*$/x ) {
$area_key = $1;
}
elsif (/^\s* } \s*$/x) {
undef $area_key
}
elsif ( defined($area_key) and /\barea\b/ and
exists $new_area{ $area_key }
) {
s/(area\s*:\s*)[\d.]+/$1$new_area{$area_key}/
}
print;
}
cell (a) {
area : 1
}
cell (b) {
area : 2
}
cell (c) {
area : 3
}
... etc ...