我希望从下面的数据中找出一些参数。
例如,如果我只想采用第4列PPST和第5列VDDIFF,如何编写计数器以获取文件中包含PPST和VDDIFF的所有数据?
如果一个文件有十个设备,我怎样才能获得所有十个设备的数据?
我的代码如下,但只需要一次。
Device#: 12
Number Site Result Test Name Pin Channel Low Measured High Force Loc
0 1 PASS PPST VDDIFF 5 -500.0000 uA 3.8867 uA 1.0000 mA 300.0000 mV 0
1 1 PASS PPST VDDSE 6 -500.0000 uA 19.2512 uA 1.0000 mA 300.0000 mV 0
2 1 PASS PPST VDDPLL 7 -500.0000 uA 15.6106 uA 1.0000 mA 300.0000 mV 0
3 1 PASS PPST VDDIO 4 -500.0000 uA 19.4656 uA 1.0000 mA 300.0000 mV 0
4 1 PASS Cont2gnd CPUC0 21 -1.0000 V -432.2093 mV -200.0000 mV -100.0000 uA 0
5 1 PASS Cont2gnd CPUT0 4 -1.0000 V -432.2228 mV -200.0000 mV -100.0000 uA 0
Device#: 50
Number Site Result Test Name Pin Channel Low Measured High Force Loc
0 1 PASS PPST VDDIFF 5 -500.0000 uA 3.6867 uA 1.0000 mA 300.0000 mV 0
1 1 PASS PPST VDDSE 6 -500.0000 uA 19.2512 uA 1.0000 mA 300.0000 mV 0
2 1 PASS PPST VDDPLL 7 -500.0000 uA 15.6106 uA 1.0000 mA 300.0000 mV 0
3 1 PASS PPST VDDIO 4 -500.0000 uA 19.4656 uA 1.0000 mA 300.0000 mV 0
4 1 PASS Cont2gnd CPUC0 21 -1.0000 V -432.2093 mV -200.0000 mV -100.0000 uA 0
5 1 PASS Cont2gnd CPUT0 4 -1.0000 V -432.2228 mV -200.0000 mV -100.0000 uA 0
Device#: 51
Number Site Result Test Name Pin Channel Low Measured High Force Loc
0 1 PASS PPST VDDIFF 5 -500.0000 uA 3.5867 uA 1.0000 mA 300.0000 mV 0
1 1 PASS PPST VDDSE 6 -500.0000 uA 19.2512 uA 1.0000 mA 300.0000 mV 0
2 1 PASS PPST VDDPLL 7 -500.0000 uA 15.6106 uA 1.0000 mA 300.0000 mV 0
3 1 PASS PPST VDDIO 4 -500.0000 uA 19.4656 uA 1.0000 mA 300.0000 mV 0
4 1 PASS Cont2gnd CPUC0 21 -1.0000 V -432.2093 mV -200.0000 mV -100.0000 uA 0
5 1 PASS Cont2gnd CPUT0 4 -1.0000 V -432.2228 mV -200.0000 mV -100.0000 uA 0
open( OUT, ">$outfile" );
open( INF, "$infile1" ) || die( " cannot open input file \n" );
$count = 0;
$Anam = 'VDDIFF';
$Nnam = 'PPST';
printf OUT ( "Unit# Test_Name Pin_Name Measure_Data; \n" );
#while ($line1 ne "")
while ( <INF> ) {
@temp1 = split( /\s+/, $_ ); #($checkR1 eq "R1")
if ( $temp1[2] eq "1" ) { # site =1 on datalog
print "1 $Nnam $Anam\n";
$Tnam = "$temp1[4]"; # test name
$Pnam = "$temp1[5]"; # Pin name
print "$Tnam $Pnam \n";
print "\n";
if ( ( $Pnam eq $Anam ) & ( $Tnam eq $Nnam ) ) {
$count = $count + 1;
}
else {
$count = 1;
}
$Anam = $Pnam; # save as previous Pnam
$Nnam = $Tnam; # save as previous Tnam
$Mval = "$temp1[9]";
$Unum = "$temp1[10]";
printf OUT ( "$count $Tnam $Pnam $Mval $Unum\n" );
}
else {
printf OUT "$_\n";
}
}
close( INF ) || die "cannot close file1 !!";
close( OUT );
print "all done\n";
Unit# Test_Name Pin_Name Measure_Data;
12 PPST VDDIFF 3.8867 uA
50 PPST VDDIFF 3.6867 uA
51 PPST VDDIFF 3.5867 uA
答案 0 :(得分:1)
你好像写了很多不必要的代码。我猜你已经采取了别人的程序来处理相同的输入文件,并试图为了你自己的目的修改它。在让别人为你工作之前,你应该认真努力解决自己的问题
这个程序做我认为你想要的。它期望输入文件的路径作为命令行上的参数,并将输出发送到STDOUT
,可以使用shell将其重定向到任何地方
如果您将此源保存在ppst_vddiff.pl
中,那么您的命令行应该类似于
ppst_vddiff.pl infile > outfile
#!/usr/bin/env perl
use strict;
use warnings 'all';
my @header = ( 'Unit#', 'Test_Name', 'Pin_Name', 'Measure_Data;' );
my $format = "%-10s %-15s %-15s %-s\n";
printf $format, @header;
my $unit;
while ( <> ) {
if ( /^Device#:\s*(\d+)/ ) {
$unit = $1;
next;
}
chomp;
my @fields = split /\s{2,}/;
if ( $fields[3] eq 'PPST' and $fields[4] eq 'VDDIFF' ) {
printf $format, $unit, $fields[3], $fields[4], $fields[7];
}
}
Unit# Test_Name Pin_Name Measure_Data;
12 PPST VDDIFF 3.8867 uA
50 PPST VDDIFF 3.6867 uA
51 PPST VDDIFF 3.5867 uA
答案 1 :(得分:-1)
好的,首先关闭:
use strict;
和use warnings 'all';
放在代码顶部。它们会阻止许多错误,这些错误会在以后绊倒你open ( my $input, '<', $infile )
open
的返回代码,因为你以后会为自己节省一些痛苦。 从这一点来看,你的问题比你想象的要简单 - 你有Device#:
表示的记录,所以我们可以设置一个记录分隔符。 $/
。
然后我们可以将您的数据块分解为行。我建议而不是使用数组指示,你最好在hash
中使用命名字段:
#!/usr/bin/env perl
use strict;
use warnings;
open( my $output, '>', $outfile ) or die $!;
open( my $input, '<', $infile1 ) or die $!;
my $pin_name = 'VDDIFF';
my $test_name = 'PPST';
local $/ = 'Device#:';
#print header row - tab separated
print {$output} join( "\t", "Unit#", "Test_Name", "Pin_Name", "Measure_Data" ),"\n";
while (<$input>) {
s/\b \b/_/g; #turn "Test Name" into "Test_Name"
#split this current chunk on linefeeds
my @rows = split(/\n/);
#pop the first line, and extract the number from it
my ($device_id) = shift(@rows) =~ m/(\d+)/;
next unless $device_id;
my @header = split( ' ', shift(@rows) ); #read a header row
for (@rows) {
my %this_row;
@this_row{@header} = split;
if ( defined $this_row{'Test_Name'}
and $this_row{'Test_Name'} eq $test_name
and $this_row{'Pin'} eq $pin_name )
{
print {$output} join( "\t",
$device_id,
$this_row{'Test_Name'},
$this_row{'Pin'},
$this_row{'Measured'} ),
"\n";
}
}
}
close($input);
close($output);