用于更新带有记录的文件内容的Perl脚本

时间:2018-01-11 17:28:56

标签: regex perl

我有一个包含用户详细信息的文件。我编写了一个perl脚本来更新该文件的内容,只更新用户名。 以下是文件内容的格式 -

//Details of John
User John is
  details1:(group = "abc")
  end detail1;
  detail2:(team = "pqr")
  end detail2;
  other_detail1:(someOtherDetail = John_123)
  end other_detail1;
end user John;

格式规则允许以下 -
1)内容可以是大写字母(例如,USER John ...... END USER John;)
2)最后一行可以写成 -
2.1)结束; (结束后的空格数无关紧要)
2.2)最终用户约翰;
2.3)结束约翰;
3)用户名(John)可以用\ John这样的转义字符编写。在这种情况下,新文件也将包含带转义序列的用户名。

现在我只想让“约翰”换行 - “用户约翰是”& “最终用户约翰”(如果约翰在场。如果2.1约翰不在场)&其余详细信息在更新的文件中保持不变。

以下是我的perl脚本 -

#!/usr/bin/perl -w
BEGIN {undef $/;}

my $match;

my $filename = $ARGV[0];

open (INFILE, "<", $filename)  or  die "Failed to read file $filename : $! \n";

$string =  <INFILE>;
close INFILE;

$match = "(?<=user )(.*?)$ARGV[2](.*?)(?<=end )(.*?)$ARGV[2]";
$string =~ s/$match/$1$ARGV[1]$2$3$ARGV[1]/gis;

open OUTFILE, ">$ARGV[0]" || die "Failed to create $ARGV[0]\n";
print OUTFILE ($string);
close OUTFILE;

此脚本的输入格式为 - myscript filepath new_name old_name

这适用于上面解释的每个规则,除了2.1。请建议一种方法,以便$ match可以适用于规则2.1。
另外我想知道在任何情况下,细节结束是否会影响“最终用户......”因为我在$ match中使用了结尾。

1 个答案:

答案 0 :(得分:0)

我认为你在这里犯了一个错误,因为你正在寻找一个魔法正则表达式。

相反,你应该打破你的问题,因为它更清晰,更容易写:

#!/usr/bin/env perl
use strict;
use warnings;

use Data::Dumper;

my ( $input_filename, $newname, $oldname ) = @ARGV;
open ( my $input, '<', $input_filename ) or die $!;


while ( <$input> ) { 

   #match start of user stanza
   if ( /^User $oldname is/i ) {
      #replace text
      s/\Q$oldname\E/$newname/i;
   }
   #match end of user stanza
   if ( /^end user $oldname/i )  {
         s/\Q$oldname\E/$newname/i;
   }
   print;
}

就是这样。