在 Perl 中哈希到 CSV/TSV 的转换
Hash to CSV/TSV conversion in Perl
我试图在 Perl 中将一个简单的散列转换为 CSV/TSV。现在,棘手的部分是由于一些有趣的原因我无法使用 Text::CSV::Slurp
,我只能使用 Text::CSV_XS
和 Text::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 上实现逻辑。
如果我没看错的话,这就是您想要的:
#!/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 个参数 open
:
的词法文件句柄
open ( my $output, '>', 'file.csv' ) or die $!;
# ...
$csv -> print ( $output, ### everything else
我试图在 Perl 中将一个简单的散列转换为 CSV/TSV。现在,棘手的部分是由于一些有趣的原因我无法使用 Text::CSV::Slurp
,我只能使用 Text::CSV_XS
和 Text::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 上实现逻辑。
如果我没看错的话,这就是您想要的:
#!/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 个参数 open
:
open ( my $output, '>', 'file.csv' ) or die $!;
# ...
$csv -> print ( $output, ### everything else