情节可以很简单 发表于 2018-01-15 16:56

从TXT提取特定列数据存到Excel中

本帖最后由 情节可以很简单 于 2018-01-16 17:24 编辑

哪位大神能提供下 下面两种模块的安装包啊,或给个指引,没用过这个模块。
我用Windows系统处理数据,可是开头就给我难住了,这些指令无法执行。
我搜了好多网址啥的都不行啊!
use Win32::OLE
use Spreadsheet::WriteExcel
另外我在activeperl安装路径中发现了OLE.pm及一些文件夹,那怎么不能用呢。

q1208c 发表于 2018-01-15 18:45

activeperl 有自己的模块管理。好象说 activepm什么的。

情节可以很简单 发表于 2018-01-16 17:11

本帖最后由 情节可以很简单 于 2018-01-16 17:19 编辑

处理学习实践阶段,求指导!谢谢!!!
我把要处理的文本放这吧,不用输入到Excel了。

输入文本A为:下面是输入文本的一部分(省略号下面还有一些无用的英文说明),
其他部分的格式也是这样,但行数量有异。
=========================================================
    Device#: 19-24

die position: (-7,1)   site 2
die position: (-6,1)   site 3
die position: (-5,1)   site 4
die position: (-4,1)   site 5
die position: (-3,1)   site 6
die position: (-2,1)   site 7

NumberSite   Result   Test Name   Channel       Low            Measured            High         
0            4      PASS   Con               56      -1.0000 V      -395.4362 mV   -100.0000 mV      
0            5      PASS   ib_trim1         58      -1.0000 V      -555.5970 mV   -100.0000 mV            
1            4      FAIL      Con               40      -1.0000 V      -405.8470 mV   -100.0000 mV      
1            2      PASS   ib_trim0         42      -1.0000 V      -556.9597 mV   -100.0000 mV               
2            4      FAIL      ib_trim0         57      -1.0000 V      -398.5833 mV   -100.0000 mV         
2            5      PASS   Con               59      -1.0000 V      -553.6025 mV   -100.0000 mV         
.................................................................

输出文本B为:“PASS”的 ib_trim 对应的site坐标及 Measured 值。

Device#: 19-24
(-4,1)      ib_trim1   -555.5970 mV
(-7,1)      ib_trim0   -556.9597 mV
#-----------------------------------------以下我的程序只实现了相关列提取:但是坐标不会匹配。
Device#: 19-24
5      ib_trim1   -555.5970 mV
2      ib_trim0   -556.9597 mV

523066680 发表于 2018-01-16 19:17

回复 3# 情节可以很简单

粗略地写一个
use Modern::Perl;
STDOUT->autoflush(1);

my $file = "src.txt";
open my $fh, "<", $file or die "$!";
my $line;
my %site;

while ( $line = <$fh> )
{
    if ( $line=~/^die position: (.*)\s+site (\d+)/i )
    {
      $site{ $2 } = $1;
    }

    if ( $line=~/\d+\s+(\d+)\s+PASS\s+(ib_trim\d+).*?(-?\d+\.\d+ mV)/i )
    {
      printf "%s\t%s\t%s\n", $site{$1}, $2, $3;
    }
}
close $fh;

523066680 发表于 2018-01-16 19:44

或者先把数据存到哈希表中,可以按标题查询

use Modern::Perl;
STDOUT->autoflush(1);

my $file = "src.txt";
open my $fh, "<", $file or die "$!";
my $line;
my %site;
my @title;
my @table;
my $ti;

while ( $line = <$fh> )
{
    if ( $line=~/^die position: (.*)\s+site (\d+)/i )
    {
      $site{ $2 } = $1;
    }
    elsif ( $line=~/^Number/ )
    {
      @title = split /\s{2,}/, $line;
    }
    elsif ( $line=~/^\d+\s+/ )
    {
      $ti = 0;
      push @table, { map { $title[$ti++] => $_ } split /\s{2,}/, $line };
    }
}
close $fh;

for my $d ( @table )
{
    if ( $d->{'Result'} =~/PASS/i and $d->{'Test Name'}=~/ib_trim/i )
    {
      printf "%s\t%s\t%s\n", $site{$d->{'Site'}}, $d->{'Test Name'}, $d->{'Measured'};
    }
}

情节可以很简单 发表于 2018-01-17 15:41

本帖最后由 情节可以很简单 于 2018-01-17 16:45 编辑

回复 5# 523066680

谢谢回复!我有点不知道该怎么描述:
1.首先我用的是Windows系统,modern::perl 我从CPAN下载了包在perl路径下解压了。
但运行程序时依然提示错误(就把他#注释掉了),所以我开头变为:
#!C:\perl64\bin
use strict;
use warnings;
use 5.016;
use autodie;

这样您提供的两个脚本输出结果是正确的!(我用三楼贴出来的部分文本示例)...

2.当我用 我的源文件为输入时,提示错误(这是我之前表述简略造成的,抱歉):
第一个脚本这句“if ( $line=~/\d+\s+(\d+)\s+PASS\s+(ib_trim\d+).*?(-?\d+\.\d+ mV)/i )”中我的源数据后面单位“mV”不是固定的

第二个脚本“if ( $d->{'Result'} =~/PASS/i and $d->{'Test Name'}=~/ib_trim/i )”
错误提示“Use of unintialized value in pattern match <m/ /> at a.pl line 41”

这个原因我在想可能是因为我的源文件 标题和下面对应数据 不是对齐的,这个该怎么办,我之前提取的时候是按列(电流单位也占一列):“print C (split),"\t",(split),"\t",(split)," ",(split),"\n";”

下面是源文件局部:是两个部分数据的交界处(每一部分都是以“Device#:x~y ” 开始,且每一部分的坐标“die position:”也是不同的)。
...       .   ....      .......                      .........         ............          ............            ............   
8       1    FAIL   ib_trim3                  test-1      -1.2800 uA   -2.1310 uA   -960.0000 nA      
8       2    FAIL   ib_trim3                  test-1      -1.2800 uA   -544.6071 pA   -960.0000 nA      
8       3    FAIL   ib_trim3                  test-1      -1.2800 uA   762.9061 pA    -960.0000 nA      
8       4    FAIL   ib_trim3                  test-1      -1.2800 uA   -23.0533 nA    -960.0000 nA      

Site Failed tests/Executed tests
------------------------------------
    0       5       9
    1       5       9
    2       5       9
    3       5       9
    4       5       9

Site    Sort   Bin
------------------------------------
    0      40       4
    1      40       4
    2      40       4
    3      40       4
    4      40       4
=========================================================================
    Device#: 6-10

die position: (7,1)   site 0
die position: (8,1)   site 1
die position: (9,1)   site 2
die position: (10,1)   site 3
die position: (11,1)   site 4

NumberSite Result   Test Name       Pin   Channel Low            Measured       High            
0       0    PASS   Con                     test75      -1.0000 V      -546.8680 mV   -100.0000 mV         
0       1    PASS   Con                     test74      -1.0000 V      -559.3652 mV   -100.0000 mV         
0       2    PASS   Con                     test73      -1.0000 V      -556.2122 mV   -100.0000 mV         
0       3    PASS   Con                     test72      -1.0000 V      -560.9373 mV   -100.0000 mV   
0       4    PASS   Con                     test15      -1.0000 V      -545.2946 mV   -100.0000 mV         
1       0    FAIL      ib_trim1                  test-1      -1.2800 uA   -1.1330 nA       -960.0000 nA      
1       1    FAIL      ib_trim1                  test-1      -1.2800 uA   -2.5713 nA       -960.0000 nA   
1       2    FAIL      ib_trim1                  test-1      -1.2800 uA   -915.8693 nA   -960.0000 nA      
1       3    PASS   ib_trim1                  test-1      -1.2800 uA   -1.1828 uA      -960.0000 nA         
1       4    FAIL      ib_trim1                  test-1      -1.2800 uA   3.0930 nA      -960.0000 nA         
2       0    PASS   ib_trim0                  test-1      -1.2800 uA   -1.0120 uA      -960.0000 nA      
...       ..    ......       .........                  .........          ............      ..............       ................   




523066680 发表于 2018-01-18 10:03

本帖最后由 523066680 于 2018-01-18 12:38 编辑

回复 6# 情节可以很简单

哦,后面的多了一个Pin列。能不能发一个更完整的源文件(压缩)上来,或者上传网盘。

第二个代码找出问题了
Number,Site Result,Test Name,Pin,Channel Low,Measured,High

Site Result 是两个列的抬头,Test Name 是单个列的抬头,中间都是一个空格。

前三列的数据内容是等宽的,1楼给出的示例是这样的 (Site 和 Result 之间有多个空格,可以作为区分):
NumberSite   Result
0            4      PASS   
0            5      PASS
1            4      FAIL   
后面补充的示例是这样的(Site 和 Result 之间只有1个空格)?
NumberSite Result
0       0    PASS
0       1    PASS
0       2    PASS
https://gist.coding.net/u/ViANG/b6a859d73042403494be6fd74836e6a3

523066680 发表于 2018-01-18 11:13

本帖最后由 523066680 于 2018-01-18 12:33 编辑

use strict;
use warnings;
STDOUT->autoflush(1);

my $file = "src_more.txt";
open my $fh, "<", $file or die "$!";
my $line;
my %site;
my @title;
my @table;
my $ti;

while ( $line = <$fh> )
{
    if ( $line=~/Device#.*/ )
    {
      dump_table(\@table) if @table;
      print $&, "\n";
      @title = ();
      @table = ();
      %site= ();
    }

    elsif ( $line=~/^die position: (.*)\s+site (\d+)/i )
    {
      $site{ $2 } = $1;
    }
   
    elsif ( $line=~/^Number/ )
    {
      @title = map { $_ !~/Test Name/i ? split " ", $_ : $_ } split /\s{2,}/, $line;
      # 只有 Test Name 是包含空格的 title
    }

    elsif ( $line=~/^\d+\s+/ )
    {
      $ti = 0;
      push @table, { map { $title[$ti++] => $_ } split /\s{2,}/, $line };
    }
}
close $fh;
dump_table(\@table) if @table;

sub dump_table
{
    my $table = shift;
    for my $d ( @$table )
    {
      if ($d->{'Result'}   =~/PASS/i
                and
            $d->{'Test Name'}=~/ib_trim/i )
      {
            printf "%s\t%s\t%s\n",
                $site{ $d->{'Site'} },
                $d->{'Test Name'},
                $d->{'Measured'}
                ;
      }
    }
}
Device#: 19-24
(-4,1)      ib_trim1    -555.5970 mV
(-7,1)      ib_trim0    -556.9597 mV
Device#: 6-10
(10,1)      ib_trim1    -1.1828 uA
(7,1)       ib_trim0    -1.0120 uA

iamlimeng 发表于 2018-01-28 10:47

ActivePerl用PPM安装模块,在运行框输入PPM回车即可。

给一段excel文件生成代码,供你参考:
#!/usr/bin/perl

use strict;
use warnings;
use Spreadsheet::WriteExcel;

my $file = "Excel_Example.xls";
my $workbook = Spreadsheet::WriteExcel->new($file);
$workbook->set_properties(
        title    => 'Excel_Example',
        author   => 'Limeng',
         company=> 'BlueIdea Software Lab.',
);
my $worksheet = $workbook->add_worksheet('Limeng');

# Create a format for the column headings
my $header = $workbook->add_format(
        font => 'Arial',
        bold => 1,
        size => 12,
        color => 'blue',
        align => 'center',
        valign => 'vcenter',
);
my $red = $workbook->add_format(
        size => 11,
        align => 'right',
        valign => 'vcenter',
        bg_color => 'red',
         num_format => 0x04,
);
my $pink = $workbook->add_format(
        size => 11,
        align => 'right',
        valign => 'vcenter',
        bg_color => 33,
         num_format => 0x04,
);

# Set the column width for columns 1, 2, 3 and 4
$worksheet->set_column(0, 3, 10);

# Write datas
$worksheet->write('A1','Test1',$header);
$worksheet->write('B1','Test2',$header);
$worksheet->write('C1','Test3',$header);
$worksheet->write('A2','2000',$red);
$worksheet->write('B2','-50000',$pink);
$worksheet->write('C2','=A2+B2',$red);
$workbook->close();

print "Excel file write OK!";
<>;


iamlimeng 发表于 2018-01-28 10:48

发重复了!
页: [1] 2
查看完整版本: 从TXT提取特定列数据存到Excel中