我有一个包含用户详细信息的文件。我编写了一个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中使用了结尾。
答案 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;
}
就是这样。