gpt4 book ai didi

csv - 如何使用 Perl 将文本文件解析为 csv 文件

转载 作者:行者123 更新时间:2023-12-05 09:36:52 26 4
gpt4 key购买 nike

我正在学习 Perl,并且想使用 Perl 将文本文件解析为 csv 文件。我有一个生成以下文本文件的循环:

//This part is what outputs on the text file
for $row(@$data) {
while(my($key,$value) = each(%$row)) {
print "${key}=${value}, ";
}
print "\n";
}

文本文件输出:

name=Mary, id=231, age=38, weight=130, height=5.05, speed=26.233, time=30, 
time=25, name=Jose, age=30, id=638, weight=150, height=6.05, speed=20.233,
age=40, weight=130, name=Mark, id=369, speed=40.555, height=5.07, time=30

CSV 文件所需的输出:

name,age,weight,height,speed,time
Mary,38,130,5.05,26.233,30,
Jose,30,150,6.05,20.233,25,
Mark,40,130,5.04,40.555,30

欢迎任何好的反馈!

最佳答案

这里的关键部分是如何操作您的数据以提取每行需要打印的内容。那么你最好使用模块来生成有效的 CSV,并且 Text::CSV非常好。

一个程序使用一个小哈希引用数组,模仿问题中的数据

use strict;
use warnings;
use feature 'say';

use Text::CSV;

my @data = (
{ name => 'A', age => 1, weight => 10 },
{ name => 'B', age => 2, weight => 20 },
);

my $csv = Text::CSV->new({ binary => 1, auto_diag => 2 });

my $outfile = 'test.csv';
open my $ofh, '>', $outfile or die "Can't open $outfile: $!";

# Header, also used below for order of values for fields
my @hdr = qw(name age weight);
$csv->say($ofh, \@hdr);

foreach my $href (@data) {
$csv->say($ofh, [ @{$href}{@hdr} ]);
}

使用 hashref slice 以所需顺序从 hashrefs 中提取值@{$href}{@hdr},一般是什么

@{ expression returning hash reference } { list of keys }

This returns a list of values for the given list of keys, from the hashref that the expression in the block {} must return. That is then used to build an arrayref (an anonymous array here, using []), what the module's say method needs in order to make and print a string of comma-separated-values from that list of values.

Note a block that evaluates to a hash reference, used instead of a hash name that is used for a slice of a hash. This is a general rule that

Anywhere you'd put an identifier (or chain of identifiers) as part of a variable or subroutine name, you can replace the identifier with a BLOCK returning a reference of the correct type.

Some further comments

  • Look over the supported constructor's attributes; there are many goodies

  • For very simple data you can simply join fields with a comma and print

    say $ofh join ',', @{$href}{@hdr};    

    但是使用模块构建有效的 CSV 记录要安全得多。通过在构造函数中正确选择属性,它可以处理任何合法嵌入字段的内容(其中一些可能需要大量工作才能手动正确完成)并且它调用的东西是'

  • 我明确列出了列名。相反,您可以获取 keys,然后按所需顺序sort,但这将再次需要一个硬编码列表进行排序

程序创建文件 test.csv 并向其打印预期的标题和数据行。


但是用逗号分隔这些“值”可能涉及的不仅仅是“CSV 格式”的首字母缩略词所代表的含义。这些逗号之间可能有各种各样的东西,包括逗号、换行符等等。这就是为什么最好建议始终使用库的原因。查看构造函数的选项是有用的。


以下评论提到了最初的问题。与此同时,这个解决的问题在 OP 的代码中得到了纠正,问题也得到了更新。我仍将此文本留作一些有用的一般性评论。

至于问题中的代码及其输出,根据 keys@data 的问题> HASH(address) 在输出中。

那个字符串 HASH(0x...) 是在打印一个变量时输出的,它是一个哈希引用(不能显示任何哈希的内容)。 Perl 通过 stringifying 处理这样的打印(从更复杂的东西中生成可打印的字符串)以这种方式引用。

没有充分的理由为散列键提供散列引用。所以我建议你检查你的数据及其处理,看看它是如何产生的。 (或者简要地展示这个,或者如果无法将其添加到这个问题中,则发布另一个问题。)

您可以用来绕过的一种方法是仅使用您知道有效的 key 列表,就像我上面显示的那样;但是,那么您可能会留下一些未处理的彻底错误。所以我宁愿建议找出问题所在。

关于csv - 如何使用 Perl 将文本文件解析为 csv 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64868909/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com