【问题标题】:Hash to CSV/TSV conversion in PerlPerl 中的哈希到 CSV/TSV 转换
【发布时间】:2016-04-03 00:10:39
【问题描述】:

我正在尝试在 Perl 中将简单的哈希转换为 CSV/TSV。现在,棘手的部分是由于一些有趣的原因我无法使用Text::CSV::Slurp,而我只能使用Text::CSV_XSText::CVS

问题描述:

我能够从我拥有的散列创建一个 CSV 文件,但显示的值并不是我希望的那样。

例子:

这是我的哈希的样子:

`$VAR1 = {
          '2015-12-09 10:49:00' => '750 mW',
          '2015-12-09 10:49:02' => '751 mW'
        };`

我希望键位于一个选项卡下,值位于另一个选项卡下。相反,我得到了一个 CVS,它的所有内容都处于逗号分隔状态。

期望的输出:

key1   value1
key2   value2 

实际输出:

key1  value1   key2   value2 

这是我的代码现在的样子:

open(DATA, "+>file.csv") || die "Couldn't open file file.csv, $!";
my $csv = Text::CSV_XS->new();
if ($input == 19){ 
    my $status = $csv->print (\*DATA, \@{[%hash1]});
}
elsif ($input == 11){
    my $status = $csv->print (\*DATA, \@{[%hash2]});
}
close(DATA) || die "Couldn't close file properly";

我在 Stack Overflow 和 Perl Monks 中遇到了许多问题,但不知何故,如果不使用 Text::CSV::Slurp,我无法找到解决方案。

请帮忙。

P.S:%hash1%hash2 是具有基本键值对的简单散列,目前还不是散列的散列。但是,随着代码的发展,我可能还必须在 HoH 上实现逻辑。

【问题讨论】:

  • 你没有哈希数组,所以 Text::CSV::Slurp 无论如何都不是正确的工具。
  • @ThisSuitIsBlackNot:我使用@{[%hash2]} 将其声明为哈希数组,然后取消引用它。在任何情况下,$csv->print 只接受数组取消引用。
  • Text::CSV::Slurp 将单个哈希引用转换为单个 CSV 行。您正在尝试将单个哈希引用转换为多个 CSV 行。即使您将散列放在这样的数组中, Text::CSV::Slurp 也不会将其拆分为多行;这不是它的设计目的,所以它不是适合这项工作的工具。
  • @ThisSuitIsBlackNot 感谢您的提示。看起来我得到了我正在寻找的东西。这个信息很方便。下次会尽量记住这一点。

标签: perl csv hash export-to-csv


【解决方案1】:

如果我没看错,那么你所追求的是这样的:

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

use Text::CSV;

my $VAR1 = {
          '2015-12-09 10:49:00' => '750 mW',
          '2015-12-09 10:49:02' => '751 mW'
        };
        
my $csv = Text::CSV -> new ( { sep_char => "\t", eol => "\n", binary => 1 } );
foreach my $key ( sort keys %{$VAR1} )  {
    $csv -> print ( \*STDOUT, [ $key, $VAR1 -> {$key} ] );
}

(或者,如果您使用的是哈希,而不是哈希参考):

foreach my $key ( sort keys %hash ) { 
     $csv -> print ( \*STDOUT, [ $key, $hash{$key} ] );
}

注意 - 这是显式排序,因为哈希是无序的。您看起来正在使用可排序的日期格式,所以这应该没问题,但是您可能需要将数据解析为一个纪元并基于它进行解析。

输出

"2015-12-09 10:49:00"   "750 mW"
"2015-12-09 10:49:02"   "751 mW"

注意 - TSV 会嵌入引号,因为字段包含空格。您可以通过以下方式删除它们:

my $csv = Text::CSV -> new ( { sep_char => "\t", 
                               eol => "\n", 
                               binary => 1, 
                               quote_char => undef } );

我强烈建议不要使用DATA 作为您的输出文件句柄,因为它已经在perl 中使用。事实上,我建议使用 3 arg open 的词法文件句柄:

open ( my $output, '>', 'file.csv' ) or die $!;

# ...

$csv -> print ( $output, ### everything else

【讨论】:

  • 感谢一百万的回答。我只是稍微调整了一下以符合我的要求。赞成并接受您的回答。
猜你喜欢
  • 2014-06-18
  • 2013-07-09
  • 1970-01-01
  • 2012-04-26
  • 1970-01-01
  • 2014-08-10
  • 1970-01-01
  • 2010-11-04
  • 2012-11-11
相关资源
最近更新 更多