编辑:我试图创建一个简短的脚本来调用输入固定宽度文件和一个文件,其中包含每个属性的起始位置和长度,然后将文件输出为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
答案 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";
}