0

以下问题:

我有一个分隔文件,其中行有 25 或 26 个字段。对于所有有 25 个字段的行,我需要在第 13 个字段之后添加一个空行,这样它也将有 26 个字段。

老的:

Z|432651242|987654321|XYZ|Abc|DEFEF||Abc-De-Fg|18|33221|Qwerty|18.06.3213|abc||123|Tepp|11.07.4443|2|||||4433322342344||

新的:

Z|432651242|987654321|XYZ|Abc|DEFEF||Abc-De-Fg|18|33221|Qwerty|18.06.3213|abc|||123|Tepp|11.07.4443|2|||||4433322342344||

我设法过滤了需要更改的行:

#!/usr/bin/perl
use strict;
use warnings;

my (@cols,$fieldLength,);
while(<>){
  @cols = split('\|', $_);
  $fieldLength=@cols;
  if ($fieldLength==25){
  print $_;
  }
}

我的想法是替换分隔符“|” 在第 13 次出现“||”,但无法做到。我试图用谷歌搜索,但这些例子对我不起作用。

有人可以帮我吗?

我也很欣赏使用 CPAN 的 CSV 模块的解决方案。

4

2 回答 2

1

您可以使用Text::CSV来解析行,插入一个带有拼接的空行,然后打印出来。像这样的东西应该工作:

use strict;
use warnings;
use Text::CSV;

my $csv = Text::CSV->new({
    sep_char => '|',
    eol      => $/,
});

while (my $row = $csv->getline(*ARGV)) {
    splice(@$row, 12, 0, '') if @$row == 25;
    $csv->print(*STDOUT, $row);
}
于 2013-08-05T21:07:21.077 回答
1

如果您可以安全地假设分隔符|永远不会出现在字段的数据中,那么您可以使用splitand splice,但Text::CSV更安全。

#!/usr/bin/perl
use strict;
use warnings;

while (<>)
{
    my @cols = split /[|]/;
    if (scalar(@cols) == 25)
    {
        splice(@cols, 13, 0, '');
        $_ = join('|', @cols);
    }
    print;
}

这似乎产生了您想要的输出。给定输入文件:

Z|432651242|987654321|XYZ|Abc|DEFEF||Abc-De-Fg|18|33221|Qwerty|18.06.3213|abc||123|Tepp|11.07.4443|2|||||4433322342344||
Z|432651242|987654321|XYZ|Abc|DEFEF||Abc-De-Fg|18|33221|Qwerty|18.06.3213|abc|def|123|Tepp|11.07.4443|2|||||4433322342344||

(其中第二行def代替了一个空字段,因此您可以准确地看到插入发生的位置),输出为:

Z|432651242|987654321|XYZ|Abc|DEFEF||Abc-De-Fg|18|33221|Qwerty|18.06.3213|abc|||123|Tepp|11.07.4443|2|||||4433322342344||
Z|432651242|987654321|XYZ|Abc|DEFEF||Abc-De-Fg|18|33221|Qwerty|18.06.3213|abc||def|123|Tepp|11.07.4443|2|||||4433322342344||
于 2013-08-05T22:16:25.137 回答