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