130723,-001,1.14,130725,+002,4.20,130731,+006,1.52,130728
130725,+002,4.20,130731,+006,1.52,130728,-003,0.00,130731
130731,+006,1.52,130728,-003,0.00,130731,+003,1.00,130731
130728,-003,0.00,130731,+003,1.00,130731,+000,0.00,130729
130731,+000,0.00,130729,-002,1.00,130728,-001,0.00,130728
以上是日志文件的一部分。日志文件中的每一行始终具有相同的长度,并且具有与上面所示相同的模式。我需要读取文件并将每行中位置42到46的所有行都放在一个数组中以满足某些期望。在上面的例子中,我们看到以下数字:
006 -003 003 + 000 -001
有人能指出我正确的方向吗?
编辑:
向Amon提出他的建议。
我最终得到了这段代码供将来参考。
open (FILE, $filename) or die "Couldn't open log: $!";
while (<FILE>) {
if ((split /,/)[8] == "+003"){
push @data, $_ }}
close FILE;
foreach(@data)
{
print "$_\r\n";
}
我正在考虑未来如果这个文件变得非常大我应该采取什么步骤来快速优化流程?
答案 0 :(得分:1)
如果您想按列号进行操作,则可以谨慎使用substr()
:
perl -pe '$_ = substr($_, 41, 4) . "\n"' data
您的问题要求列42..46,但使用包含表示法,选择5个位置,最后一个是逗号。指定42..46可能是基于1的半开放范围的列。
代码中的41是'42-1列'(基于0的索引); 4是'46 - 42'。因此,对于列[N..M],公式为:
perl -pe '$_ = substr($_, N-1, M-N) . "\n"' data
答案 1 :(得分:0)
虽然@ amon的答案很优雅,但你可以使用regex:
open FILE, "filename.txt" or die $!;
while (<FILE>) {
if $_ =~ /^.{41}(\+006)|(-003)|(\+003)|(\+000)|(-001)/
}
答案 2 :(得分:0)
尝试
perl -F, -ane '$F[7] eq "+003" and push @l,$_; END { print for @l }'<<XXX
130723,-001,1.14,130725,+002,4.20,130731,+006,1.52,130728
130725,+002,4.20,130731,+006,1.52,130728,-003,0.00,130731
130731,+006,1.52,130728,-003,0.00,130731,+003,1.00,130731
130728,-003,0.00,130731,+003,1.00,130731,+000,0.00,130729
130731,+000,0.00,130729,-002,1.00,130728,-001,0.00,130728
XXX
输出:
130731,+006,1.52,130728,-003,0.00,130731,+003,1.00,130731