Perl 如何将文件合并为一个CSV文件?
如果我有一个包含以下内容的文件Perl 如何将文件合并为一个CSV文件?,perl,csv,Perl,Csv,如果我有一个包含以下内容的文件FOO_1.txt: FOOA FOOB FOOC FOOD ... 还有很多其他文件FOO_files.txt。其中每一项都包括: FOOA FOOB FOOC FOOD ... 1110000000 一行包含0或1作为FOO1值的数量(fooa,foob,…) 现在我想将它们合并到一个文件FOO_RES.csv,该文件的格式如下: FOOA,1,0,0,0,0,0,0... FOOB,1,0,0,0,0,0,0... FOOC,1,0,0
FOO_1.txt
:
FOOA
FOOB
FOOC
FOOD
...
还有很多其他文件FOO_files.txt
。其中每一项都包括:
FOOA
FOOB
FOOC
FOOD
...
1110000000
一行包含0
或1
作为FOO1
值的数量(fooa
,foob
,…)
现在我想将它们合并到一个文件FOO_RES.csv
,该文件的格式如下:
FOOA,1,0,0,0,0,0,0...
FOOB,1,0,0,0,0,0,0...
FOOC,1,0,0,0,1,0,0...
FOOD,0,0,0,0,0,0,0...
...
什么是简单而优雅的方式来进行
(使用哈希和数组->$hash{$key}=\@data)
非常感谢你的帮助
Yohad如果我理解正确,您的第一个文件是您的密钥顺序文件,其余文件每个密钥包含一个字节,顺序相同。您需要这些键的一个复合文件,其中每个键的数据字节都列在一起
在这种情况下,您应该同时打开所有文件。从密钥顺序文件中读取一个密钥,从每个数据文件中读取一个字节。将所有内容输出到最终文件中。对每个键重复此操作。您实际上不需要使用散列我的Perl有点生疏,所以语法可能有点不正确,但基本上是这样做的:
open KEYFILE , "foo_1.txt" or die "cannot open foo_1 for writing";
open VALFILE , "foo_files.txt" or die "cannot open foo_files for writing";
open OUTFILE , ">foo_out.txt"or die "cannot open foo_out for writing";
my %output;
while (<KEYFILE>) {
my $key = $_;
my $val = <VALFILE>;
my $arrVal = split(//,$val);
$output{$key} = $arrVal;
print OUTFILE $key."," . join(",", $arrVal)
}
你的规格不清楚。你不能有一个名为
FOO_files.txt
的“很多其他文件”,因为它只有一个名称。所以我将把它作为带有data+filelist模式的文件。在本例中,有一些文件名为FOO*.txt
,每个文件都包含“[01]+\n”
因此,我们的想法是处理文件列表文件中的所有文件,并将它们全部插入结果文件FOO_RES.csv
,以逗号分隔
use strict;
use warnings;
use English qw<$OS_ERROR>;
use IO::Handle;
open my $foos, '<', 'FOO_1.txt'
or die "I'm dead: $OS_ERROR";
@ARGV = sort map { chomp; "$_.txt" } <$foos>;
$foos->close;
open my $foo_csv, '>', 'FOO_RES.csv'
or die "I'm dead: $OS_ERROR";
while ( my $line = <> ) {
my ( $foo_name ) = ( $ARGV =~ /(.*)\.txt$/ );
$foo_csv->print( join( ',', $foo_name, split //, $line ), "\n" );
}
$foo_csv->close;
使用严格;
使用警告;
使用英语qw;
使用IO::Handle;
打开我的$foos,“看起来您有许多foo_文件,其中有一行,类似于:
1110000000
代表什么
fooa=1
foob=1
fooc=1
food=0
fooe=0
foof=0
foog=0
fooh=0
fooi=0
fooj=0
看起来你的食物只是这些值的总和?在这种情况下,您不需要数组的散列,只需要一个散列
my @foo_files = (); #NOT SURE HOW YOU POPULATE THIS ONE
my @foo_keys = qw(a b c d e f g h i j);
my %foo_hash = map{ ( $_, 0 ) } @foo_keys; # initialize hash
foreach my $foo_file ( @foo_files ) {
open( my $FOO, "<", $foo_file) || die "Cannot open $foo_file\n";
my $line = <$FOO>;
close( $FOO );
chomp($line);
my @foo_values = split(//, $line);
foreach my $indx ( 0 .. $#foo_keys ) {
last if ( ! $foo_values[ $indx ] ); # or some kind of error checking if the input file doesn't have all the values
$foo_hash{ $foo_keys[$indx] } += $foo_values[ $indx ];
}
}
my@foo_文件=()#不知道你是怎么填充这个的
my@foo_keys=qw(a b c d e f g h i j);
我的%foo_hash=map{($,0)}@foo_keys;#初始化散列
foreach我的$foo_文件(@foo_文件){
open(my$FOO,“如果你不能清楚地描述你的数据和你想要的结果,你就没有办法编写代码了——接受一个简单的项目是开始使用一种新语言的好方法
请允许我介绍一种简单的方法,您可以使用它以任何语言大量编写代码,不管您是否知道。这种方法只适用于小型项目。您需要提前为大型项目制定计划
如何编写程序:
打开你的文本编辑器,写下你拥有的数据。每一行都做一个注释
描述你想要的结果
开始描述将数据更改为所需格式所需的步骤
完成的1号和2号:
#!/usr/bin perl
use strict;
use warnings;
# Read data from multiple files and combine it into one file.
# Source files:
# Field definitions: has a list of field names, one per line.
# Data files:
# * Each data file has a string of digits.
# * There is a one-to-one relationship between the digits in the data file and the fields in the field defs file.
#
# Results File:
# * The results file is a CSV file.
# * Each field will have one row in the CSV file.
# * The first column will contain the name of the field represented by the row.
# * Subsequent values in the row will be derived from the data files.
# * The order of subsequent fields will be based on the order files are read.
# * However, each column (2-X) must represent the data from one data file.
现在你知道你拥有什么,你需要去哪里,你可以充实一下该计划需要做些什么才能让你达到目标-这是第3步:
您知道您需要字段列表,因此首先获取该列表:
# Get a list of fields.
# Read the field definitions file into an array.
由于以面向行的方式编写CSV是最容易的,所以在生成每一行之前,您需要处理所有文件。因此,您需要一个地方来存储数据
# Create a variable to store the data structure.
现在我们读取数据文件:
# Get a list of data files to parse
# Iterate over list
# For each data file:
# Read the string of digits.
# Assign each digit to its field.
# Store data for later use.
我们已将所有数据存储在内存中,现在写入输出:
# Write the CSV file.
# Open a file handle.
# Iterate over list of fields
# For each field
# Get field name and list of values.
# Create a string - comma separated string with field name and values
# Write string to file handle
# close file handle.
现在,您可以开始将注释转换为代码。每个注释可以有1到100行代码。您可能会发现您需要做的事情非常复杂,您现在不想承担。制作一个虚拟子例程来处理复杂的任务,并忽略它,直到您完成所有其他操作。现在您可以独自解决这个复杂、棘手的子问题
由于您刚刚学习Perl,您需要点击文档,了解如何执行您编写的注释所表示的每个子任务。这类工作的最佳资源是。这也将派上用场。由于您需要使用复杂的数据结构,您还需要阅读
您可能想知道,对于给定的问题,您应该如何知道应该阅读哪些perldoc页面。关于Perlmonks的一篇标题为的文章很好地介绍了文档以及如何使用它
最棒的是,如果你陷入困境,当你寻求帮助时,你可以分享一些代码。更清楚地解释csv的列是如何产生的。根据你的问题,我的印象是你接受了一项你不知道如何做的工作。你现在正试图通过让我们为你解决每一步来完成它。在这个过程中如果混淆信息,使你的雇主/客户/老师无法理解你在做什么,你就把问题变成了难以辨认的混乱。如果有人能解释这个问题到底是怎么回事,或者你能澄清大局,我将不胜感激。毕竟,帮助那些试图帮助你的人是有帮助的我想对你说。我似乎是唯一一个对你的问题做出正面回答的人。你可能想对那些试图帮助你的人表示更多的感激。也许他不知道这个网站是如何运作的,或者可能答案没有帮助!正如我所说,我是新来的!我很荣幸能从你那里得到答案。我非常感谢你的回答。我不知道这个网站是如何工作的,也不知道有关Perl的很多内容,这就是我感谢您的指导的方式。因为我在一天结束时打印了我的问题,所以在新的一天开始之前,我无法检索任何消息:)再次感谢!@Byron:你的代码不会编译,也不会按照你的想法运行。对open
的调用中缺少必需的逗号,如果没有规范,open
将始终打开一个文件进行读取。因此,这些都不是用于编写的文件句柄。正如我所说的,我的perl已经生锈了,我只是想强调一下t如果读卡器是c