Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell 如何在perl中替换某个关键字后的行 rerun.txt_Shell_Perl - Fatal编程技术网

Shell 如何在perl中替换某个关键字后的行 rerun.txt

Shell 如何在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被相应哈希元素的值替换

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就会打印到STDOUT


我依靠一些比较喜欢正则表达式的人来尝试对可能的输入进行防御,并结合一些步骤。在您的案例中,建议使用最后一个标签作为替代,但我希望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 ...