下面提到的文件用于提供对代码存储库的访问。
cat /home/user/file
@abc_dev_group = @rel_team ram_ji jack_daniel tom_alter
@DEF_release-25Apr_dev_group= @rel_team @SDV_dev_group
@Ship_dev_group= udit_srinivasan himanshu_singhal vishal_tripathi
@Ship_release-15Jan2010_group = @release_team
repo cust
RW+ dev* = @And_dev_group
@And_dev_group = @rel_team piyush_rastogi naveen_srivastava arpit_chandra
我需要在包含以@开头并以'_dev_group'结尾的字符串的行中搜索 user
例如,@Ship_dev_group
此类字符串后跟空格(可选),后跟等号(=),然后是用户名。一旦我搜索给定用户并发现该特定用户不在,我就会在该行中附加该用户的姓名。
我在下面编写了这段代码,但它似乎不起作用。实际上它对某些人有用但对其他人失败了。尝试了许多不同的变化,但无法让它适用于所有人。
use strict;
use warnings;
my ($FILE, $repo);
my $user_name = "john_doe";
my $input_file = "/home/user/file";
my @repository_list = ("abc", "DEF","Ship", "And");
open (FILE, "<", $input_file) || die "Could not open file [$input_file]: $!";
foreach my $repo (@repository_list) {
if ( ! grep {/^\@${repo}_dev_group.*$user_name.*/} <FILE> ) {
system ("sed -i \"s/^\\(\@${repo}_dev_group.*\\)/\\1 $user_name/\" $input_file");
} else {
printf "User entry already exists in file $input_file\n";
}
}
close FILE || die "Could not close file [$input_file]: $!";
我还使用print语句查看发生了什么。它确实显示了正确的(假设)正则表达式,它也适用于命令行(Linux框)(虽然我知道bash和Perl正则表达式表现不同)但它不能通过这个脚本。
更新
该脚本现在正在运行。 :)请看下面我添加评论的行:
open (FILE, "<", $input_file) || die "Could not open file [$input_file]: $!";
@file = <FILE>; # Read into array
foreach my $repo (@repository_list) {
if ( ! grep {/^\@${repo}_dev_group.*$user_name.*/} @file ) { # grepped the array @file
system ("sed -i \"s/^\\(\@${repo}_dev_group.*\\)/\\1 $user_name/\" $input_file");
} else {
printf "User entry already exists in file $input_file\n";
}
}
close FILE || die "Could not close file [$input_file]: $!";
为什么现在开始工作?为什么早期的方法不起作用?我现在真的很困惑。
答案 0 :(得分:0)
我认为我找到了罪魁祸首:你必须使用非贪婪的量词:所以请使用.*?
代替.*
......
例如,在@And_dev_group = @rel_team piyush_rastogi naveen_srivastava arpit_chandra
之类的字符串中,您有两个and
次出现,因此正则表达式的贪婪程度将尽可能匹配,这不是您想要的...
答案 1 :(得分:0)
这将在每行上搜索给定的用户名,并打印包含它的行以及与该行关联的用户名组。
use strict;
use warnings;
my @file = ('@abc_dev_group = @rel_team ram_ji jack_daniel tom_alter',
'@DEF_release-25Apr_dev_group= @rel_team @SDV_dev_group',
'@Ship_dev_group= udit_srinivasan himanshu_singhal vishal_tripathi',
'@Ship_release-15Jan2010_group = @release_team',
'repo cust',
' RW+ dev* = @And_dev_group',
'@And_dev_group = @rel_team piyush_rastogi naveen_srivastava arpit_chandra');
my $user_name = 'jack_daniel';
my $capture;
foreach (@file){
print "$_\n" if /\@.*_dev_group\s?=(.*$user_name.*)/g;
($capture) = $1;
}
print "$capture\n";
打印
包含用户名匹配的行:
@abc_dev_group = @rel_team ram_ji jack_daniel tom_alter
该行上的所有用户名:
@rel_team ram_ji jack_daniel tom_alter
答案 2 :(得分:0)
my @file; #load your file here
@file = ('@abc_dev_group = @rel_team ram_ji jack_daniel tom_alter',
'@DEF_release-25Apr_dev_group= @rel_team @SDV_dev_group',
'@Ship_dev_group= udit_srinivasan himanshu_singhal vishal_tripathi',
'@Ship_release-15Jan2010_group = @release_team',
'repo cust',
' RW+ dev* = @And_dev_group',
'@And_dev_group = @rel_team piyush_rastogi naveen_srivastava arpit_chandra');
my $user_name = "john_doe";
my @new_file = (); #rewrite lines into this
foreach my $line (@file) {
if ($line =~ /^\@.+_dev_group\s?=\s?((.+\s?)+)$/) {
my @users = ();
push @users, split(/\s+/, $1);
$line .= " $user_name" unless (grep {$_ eq $user_name} @users);
}
push @new_file, $line;
}
foreach my $line (@new_file) {
print "$line\n";
}
最后一段代码将打印出来:
@abc_dev_group = @rel_team ram_ji jack_daniel tom_alter john_doe
@DEF_release-25Apr_dev_group= @rel_team @SDV_dev_group john_doe
@Ship_dev_group= udit_srinivasan himanshu_singhal vishal_tripathi john_doe
@Ship_release-15Jan2010_group = @release_team
repo cust
RW+ dev* = @And_dev_group
@And_dev_group = @rel_team piyush_rastogi naveen_srivastava arpit_chandra john_doe