PERL根据输入文件将宽度固定为CSV

时间:2015-02-19 21:38:43

标签: perl csv

编辑:我试图创建一个简短的脚本来调用输入固定宽度文件和一个文件,其中包含每个属性的起始位置和长度,然后将文件输出为CSV而不是固定宽度。我还没有删除空白,目前我正专注于构建文件阅读器部分。

修正: 我目前的问题是,这个代码从$ StartPosition的第三行返回数据,而第四行返回$ Length的数据,它们应该首先在COMMA的第一行找到。我不知道是什么促使这种行为。

下一期:它只读取practice_data.txt中的第一条记录我猜测它需要告诉COMMA回到开头?

while (my $sourceLine = <SOURCE>) {
   $StartPosition = 0;
   $Length = 0;
   $Output = "";
   $NextRecord ="";
   while (my $commaLine = <COMMA>) {
       my $Comma = index($commaLine, ',');
       print "Comma location found at $Comma \n";
       $StartPosition = substr($commaLine, 0, $Comma);
       print "Start position is $StartPosition \n";
       $Comma = $Comma + 1
       $Length = substr($commaLine, $Comma);
       print "Length is $Length \n";
       $NextRecord = substr($sourceLine, $StartPosition, $Length);
       $Output = "$Output . ',' . $NextRecord";
       }
   print OUTPUT "$Output \n";
}

practice_data.txt

1234512345John      Doe       123 Mulberry Lane   Columbus  Ohio      43215Johnny         Jane      
5432154321Jason     McKinny   423 Thursday Lane   Columbus  Ohio      43212Jase           Jamie     
4321543212Mike      Jameson   289 Front Street    Cleveland Ohio      43623James          Sarah      

每条记录长度为100个字符。 的 Definitions.txt:

0,10
10,10
20,10
30,20
50,10
60,10
70,5
75,15
90,10

2 个答案:

答案 0 :(得分:0)

总是有助于提供足够的信息,这样我们至少可以进行一些测试,而无需阅读您的代码并想象数据必须是什么样的。

我建议您先使用包含字段规范的文件构建模板,然后使用unpack。请注意,A字段说明符会修剪数据中的尾随空格。

使用Text::CSV模块解析或生成格式正确的CSV数据几乎是必不可少的。我使用autodie编译指示来避免必须明确检查并报告每个I / O操作的状态。

我已经使用过这个数据

<强> my_source_data.txt

12345678  ABCDE1234FGHIJK

<强> my_field_spec.txt

0,8
10,5
15,4
19,6

这个程序

use strict;
use warnings;
use 5.010;
use autodie;

use Text::CSV;

my @template;
open my $field_fh, '<', 'my_field_spec.txt';
while ( <$field_fh> ) {
  my (@info) = /\d+/g;
  die unless @info == 2;
  push @template, sprintf '@%dA%d', @info;
}

my $template = "@template";

open my $source_fh, '<', 'my_source_data.txt';

my $csv = Text::CSV->new( { binary => 1, eol => $/ } );

while ( <$source_fh> ) {
  my @fields = unpack $template;
  $csv->print(\*STDOUT, \@fields);
}

<强>输出

12345678,ABCDE,1234,FGHIJK

答案 1 :(得分:-1)

看起来您对如何阅读COMMA文件句柄的内容感到有些困惑。每次阅读<COMMA>时,您都会从该文件中读取另一行。相反,将一行读入my $line = <FH>之类的标量并改为使用:

while (my $source_line = <SOURCE>) {
    $StartPosition = 0;
    $Length = 0;
    $Output = "";
    $Input = $_;
    $NextRecord ="";
    while (my $comma_line = <COMMA>) {
        my $Comma = index($comma_line, ',');
        print "Comma location found at $Comma \n";
        $StartPosition = substr($comma_line, 0, $Comma);
        print "Start position is $StartPosition \n";
        $Length = substr($comma_line, $Comma);
        print "Length is $Length \n";
        $NextRecord = substr($Input, $StartPosition, $Length) + ',';
        $Output = "$Output$NextRecord";
    }

    print OUTPUT "$Output \n";
}