提取从文本文件中的特定数据在Perl
我是新来的Perl,我试图从一个文件,它看起来像这样提取的具体数据:提取从文本文件中的特定数据在Perl
Print of 9 heaviest strained elements:
Element no Max strain
20004 9.6 %
20013 0.5 %
11189 0.1 %
20207 0.1 %
11157 0.1 %
11183 0.0 %
10665 0.0 %
20182 0.0 %
11160 0.0 %
==================================================
我想只提取单元号(20004 ,20013等)并将它们写入一个新文件。文件的读取应该在到达行(=========)时立即结束,因为文件中稍后会有更多元素编号和相同的标题。 希望是有道理的。 任何建议非常感谢!
我现在有这样的代码,这给了我的号码列表,最大10连胜:
my $StrainOut = "PFP_elem"."_$loadComb"."_"."$i";
open DATAOUT, ">$StrainOut" or die "can't open $StrainOut"; # Open the file for writing.
open my $in, '<', "$POSTout" or die "Unable to open file: $!\n";
my $count = 0;
while(my $line = <$in>) {
last if $line =~/={10}\s*/;
if ($line =~ /% *$/) {
my @columns = split " ", $line;
$count++;
if($count % 10 == 0) {
print DATAOUT "$columns[1]\n";
}
else {
print DATAOUT "$columns[1] ";
}
}
}
close (DATAOUT);
close $in;
什么需要改变的是“我的@columns =分裂...”行。目前,只要它有'9个空格',就会分割$ line标量。由于元素数字的位数可能会有所不同,这是一种糟糕的数据提取方式。是否可以从左至右进行读取,省略所有空格并仅记录数字,直到数字后面有更多空格(百分比值被忽略)?
#!/usr/bin/perl
use strict;
use warnings;
while (<>) { # read the file line by line
if (/% *$/) { # if the line ends in a percent sign
my @columns = split; # create columns
print $columns[0], "\n"; # print the first one
}
last if /={10}/; # end of processing
}
#!/usr/bin/perl
use strict;
use warnings;
while (my $f= shift) {
open(F, $f) or (warn("While opening $f: $!", next);
my foundstart=0;
while(<F>) {
($foundstart++, next) if /^\s#Element/;
last if /\s*=+/;
print $_ if $foundstart;
}
$foundstart=0;
close(F);
}
它有编译错误。 1.“warn”指令中有一个小括号。 2.-将'foundstart'变量声明为带'$'的标量,并且在下一个正则表达式中,我认为有'#'而不是'*'的拼写错误。然后它会在我的测试中打印数字但百分比。 – Birei 2012-02-02 13:56:17
#!/usr/bin/perl
use strict;
use warnings;
open my $rh, '<', 'input.txt' or die "Unable to open file: $!\n";
open my $wh, '>', 'output.txt' or die "Unable to open file: $!\n";
while (my $line = <$rh>) {
last if $line =~ /^ ={50}/;
next unless $line =~ /^ {6}(\d+)/;
print $wh "$1\n";
}
close $wh;
您可以通过在命令shell中运行此一班轮做。
在* nix:
cat in_file.txt | perl -ne 'print "$1\n" if (m/\s*(\d+)\s*\d+\.\d+/)' > out_file.txt
在Windows上:
type in_file.txt | perl -ne "print qq{$1\n} if (m/\s*(\d+)\s*\d+\.\d+/)" > out_file.txt
但是,如果达到等号的行,他想停止从文件中读取数据。 – flesk 2012-02-02 12:25:31
这只猫是一个过程的浪费。 -n开关导致对@ARGV中的文件名进行迭代,就好像你写了LINE:while(){... – JRFerguson 2012-02-02 13:17:11
一个班轮使用触发器:
perl -ne '
if (m/\A\s*(?i)element\s+no/ .. ($end = /\A\s*=+\s*\Z/)) {
printf qq[$1\n] if m/\A\s*(\d+)/;
exit 0 if $end
}
' infile
结果:
20004
20013
11189
20207
11157
11183
10665
20182
11160
这似乎工作:我的@columns =拆分(/ \ S + /,$行); – 2012-02-02 16:18:35