我在学习Perl时花了5天的时间,遇到了这个问题。 尝试使用正则表达式从文件中提取某个字符串,然后将这些字符串放入苛刻的位置,然后仅输出唯一值,例如,文本文件包含以下字符串:
"placement Z F97342"
"placement d F97342"
"placement g F97342"
预期输出:
open(FHR, "<test.txt") or die "Cannot open file $!";
while (<FHR>){
chomp($_);
$_ =~/placement/g;
print "$_\n";
}
下面是我的代码,但是它给了我重复的带有“ placement Z”的行
{{1}}
有帮助吗?
答案 0 :(得分:3)
您误解了我想的一堆东西。您正在做一个正则表达式匹配,但实际上并没有对结果做任何事情。
您如何看待:
$_ =~/placement/g;
在做什么? (因为答案现在是“无”)。
同样-您正在“打印” $_
,因此实际上只是在打印文件中的每一行。
您需要在什么级别测试重复项?是“实线”还是仅仅是“展示位置” ID,还是紧随其后的“数字”?
但是,如果您需要测试重复项,那么您需要的是哈希值。
类似这样的方法可以解决问题:
#!/usr/bin/env perl
use strict;
use warnings;
open( my $input, '<', "test.txt" ) or die "Cannot open file $!";
my %seen;
while (my $line = <$input>) {
print $line unless $seen{$line}++;
}
也:
perltidy
并使用它。 perltidy -pbp
会将代码缩进并格式化为公认的标准。 (您可以根据自己的喜好自定义-格式/缩进可以是任何您想要的,只要它一致即可)。 chomp
。 use strict;
和use warnings;
。 如果您希望在测试行的哪一部分上有更多选择,可以使用正则表达式捕获子元素。举例来说-仅“安置信”很重要:
#!/usr/bin/env perl
use strict;
use warnings;
open( my $input, '<', "test.txt" ) or die "Cannot open file $!";
my %seen;
while ( <$input>) {
my ( $placement_id ) = m/placement (\d+)/;
print unless $seen{$placement_id}++;
}
请注意-我没有分配<$input>
的内容-它的内容设置为$_
,但我觉得作为样式点,您应该避免在代码中使用$_
-名称如果您要使用它。
之所以可行,是因为m//
正则表达式匹配和print
都默认在$_
(即“当前行”)上运行。右侧正则表达式中的捕获括号用于填充$placement_id
-但请注意,您需要 左侧的括号,否则$placement_id_
仅用于模式匹配是否为“真/假”结果。
答案 1 :(得分:2)
在这种情况下,实际上不需要显式打开文件句柄。 Perl将自动打开任何在命令行上给出名称的文件,您可以使用空文件输入运算符(<>
)读取其数据。
所以您的代码可以很简单:
#!/usr/bin/perl
use strict;
use warnings;
my %seen;
while (<>) {
print unless $seen{$_}++;
}
如果此代码位于名为filter
的文件中,则可以这样命名:
$ filter test.txt
答案 2 :(得分:1)
使用Perl单线版
> cat file.txt
"placement Z F97342"
"placement Z F97342"
"placement d F97342"
"placement g F97342"
"placement Z F97342"
> perl -ne '{ print "$_" unless $data{$_}++; } ' file.txt
"placement Z F97342"
"placement d F97342"
"placement g F97342"
>