【问题标题】:From pipe delimited to comma delimited?从管道分隔到逗号分隔?
【发布时间】:2016-09-05 16:41:22
【问题描述】:

我有一个工作脚本,它可以解析 CSV 文件、清理数据并进行一些更改,然后再将其重新组合在一起。我正在使用的原始文件是逗号分隔的。但我刚刚收到了将要运行的所有实际文件,它们都是用管道分隔的。我需要做同样的事情,然后将它们重新组合成逗号分隔的文件。

首先,我有 -

#!/usr/bin/perl/

use strict;
use warnings;
use Data::Dumper;
use Time::Piece;

my $filename = 'records.csv';

open my $FH, $filename
  or die "Could not read from $filename <$!>, program halting.";

# Read the header line.
chomp(my $line = <$FH>);
my @fields = split(/|/, $line);
print Dumper(@fields), $/;

my @data;
# Read the lines one by one.
while($line = <$FH>) {

    chomp($line);

...解析我的数据,然后目前,我以此结束将数据放回文件中-

# put the records back
    push @data, \@fields;

但是如何将数据以逗号分隔的形式放回?

【问题讨论】:

  • " 我也需要这样做,然后将它们作为逗号分隔的文件重新组合在一起" 不,你不需要,你只需要在管道上拆分数据而不是逗号,然后从那里照常进行。请不要尝试先从真实的输入文件重新创建“预期”输入文件,因为您将引入全新的错误层
  • 由于您已经(可能)成功地将每一行拆分为字段,并且您已经知道如何拆分管道字符,因此您的其余代码应该保持不变。您问题的核心似乎是 “如何将数据以逗号分隔?” 但这与原始分隔符无关,您没有显示任何与此有关的代码那。请展示您尝试过的 Perl 代码并解释它为什么不适合您,并展示一些真实的输入和输出数据
  • @BigRedEO Borodin 说您不应该将文件转换为 CSV。只需将现有代码更改为以管道而不是逗号分隔即可。
  • @BigRedEO 将什么推回什么文件?您有一个包含输入数据的管道分隔文件。您的最终目标大概是解析文件以获取每个字段的内容并对其进行处理。根据您之前的问题,听起来您已经编写了一个预处理器来从 CSV 中删除逗号、引号等,这只是一个精心设计的解决方法,以避免使用像 Text::CSV 这样的正确 CSV 解析器。现在您正尝试将管道限制文件转换为 CSV,以便您的预处理器可以处理它,但这只是 另一个 hacky 解决方法,因为(续)跨度>
  • 你可以修改你的预处理器来处理管道分隔的文件。您应该只下载 Text::CSV 的源代码并将其与您的脚本捆绑在一起,而不是所有这些基于变通办法的变通办法。 Text::CSV 只是一个 Perl 脚本,无需预处理器和预处理器。

标签: perl parsing csv split


【解决方案1】:

不要使用 split 解析 CSV 文件。使用正确的解析器。

use strict;
use warnings 'all';
use autodie;
use Text::CSV_XS;

my $csv_in = Text::CSV_XS->new( { binary => 1, sep_char => "|" } );
my $csv_out = Text::CSV_XS->new( { binary => 1, sep_char => ",", eol => $/ } );
while ( my $row = $csv_in->getline(*ARGV) ) {
    $csv_out->print( *STDOUT, $row );
}

如果是真的,您只需将分隔的管道更改为逗号分隔,将tr '|' ',' 插入到您的管道中。

【讨论】:

  • 我的脚本已经按原样运行了。只是现在我有一个以管道分隔的文件,需要将其清理并作为逗号分隔的文件重新组合在一起。 Text::CSV 对我不可用,也不会提供给我。我有什么作品。我现在只需要考虑管道。
【解决方案2】:

一些事情。首先,修复您的 shebang(#! 行),使其不包含尾随 /

其次,perl 使用正则表达式进行拆分,因此您需要在拆分时转义管道字符:

my @fields = split(/\Q|\E/, $line);

最后,您可以使用join 将数组的元素连接成一个字符串。这使用字符串文字,而不是正则表达式。

my $output_line = join(',', @fields);

【讨论】:

  • 你有变量 $output_line 把数据放回去。将它写回同一个文件将如何工作?还是必须使用不同的文件名?
  • split(/\Q|\E/, $line) 通常写成split /\|/, $line
猜你喜欢
  • 2020-07-21
  • 1970-01-01
  • 1970-01-01
  • 2019-05-21
  • 2020-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多