Print only the first word in line
我需要以下perl代码的帮助。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #!perl -w use strict; use warnings; open my $file, '<', 'ubb' or die $1; my $spool = 0; my @matchingLines; while (<$file>) { if (/GROUPS/i) { $spool = 1; next; } elsif (/SERVERS/i) { $spool = 0; print map {"$_" } @matchingLines; @matchingLines = (); } if ($spool) { push (@matchingLines, $_); } } close ($file); |
输出如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ADM LMID=GW_S4_1_PM,GW_S4_2_BM GRPNO=1 ADM_TMS LMID=GW_S4_1_PM,GW_S4_2_BM GRPNO=2 TMSNAME=TMS ADM_1 LMID=GW_S4_1_PM GRPNO=11 ADM_2 LMID=GW_S4_2_BM GRPNO=12 DMWSG_Gateway_1 LMID=GW_S4_1_PM GRPNO=101 ENVFILE="../GW_S4.Gateway.envfile" DMWSG_Gateway_2 LMID=GW_S4_2_BM GRPNO=201 ENVFILE="../GW_S4.Gateway.envfile" DMWSG_1 LMID=GW_S4_1_PM GRPNO=106 DMWSG_2 LMID=GW_S4_2_BM GRPNO=206 |
但是我只想获取每行的第一个单词(例如
请注意,该文件在此处打印的内容的上方和下方都有很多其他行。我只想对
我建议您对代码进行2次更改
注意:已使用问题中的样本数据(以及其他内容)对它们进行了测试。
I:提取
更改此
1 |
到
1 |
这会将每行的第一个单词而不是整行推入数组。
请注意,
当然,您也可以按照7stud的答案中的建议使用
II:更改
更改此
变成
或者,根据TLP的建议,
1 2 |
或
请注意,
有关
- 请参见perldoc perlvar(只需使用CTRL F在该页面中找到它们)
-
或者,您可以简单地在控制台上使用
perldoc -v '$/' 等获取这些信息。
关于可读性的注意事项
我不认为隐式正则表达式匹配,即
但是与变量匹配,即
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | use strict; use warnings; use 5.014; #say() my $fname = 'data.txt'; open my $INFILE, '<', $fname or die"Couldn't open $fname: $!"; #-->Not $1" my $recording_on = 0; my @matching_lines; for my $line (<$INFILE>) { if ($line =~ /groups/i) { $recording_on = 1; next; } elsif ($line =~ /servers/i) { say for @matching_lines; #say() is the same as print(), but it adds a newline at the end @matching_lines = (); $recording_on = 0; } if ($recording_on) { my ($first_word, $trash) = split"", $line, 2; push @matching_lines, $first_word; } } close $INFILE; |
您可以使用触发器运算符(范围)选择输入的一部分。此运算符的想法是,在LHS(左侧)返回true之前,它返回false,然后在RHS返回false之前,它返回true,然后将其重置。这有点像保存状态。
请注意,边缘线也包含在比赛中,因此我们需要将其删除。之后,使用doubleDown \\的想法并将
1 2 3 4 5 6 7 8 9 10 11 12 | use strict; use warnings; my @matches; while (<>) { if (/GROUPS/i .. /SERVERS/i) { # flip-flop remembers the matches next if (/GROUPS/i or /SERVERS/i); push @matches, /^(\\S+)/; } } # @matches should now contain the first words of those lines |