Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays Perl:将值插入CSV文件的特定列中_Arrays_Perl_Csv_File Io - Fatal编程技术网

Arrays Perl:将值插入CSV文件的特定列中

Arrays Perl:将值插入CSV文件的特定列中,arrays,perl,csv,file-io,Arrays,Perl,Csv,File Io,我有以下形式的CSV数据: S.No,Label,Customer1,Customer2,Customer3... 1,label1,Y,N,Y 2,label2,N,Y,N ... 我需要在标有Y的“客户”列左侧复制“标签”,在标有N的列左侧没有任何内容(“) 预期产出: S.No,Label,Customer1,Customer1,Customer2,Customer2,Customer3,Customer3... 1,label1,label1,Y,"",N,label1,Y 2,lab

我有以下形式的CSV数据:

S.No,Label,Customer1,Customer2,Customer3...
1,label1,Y,N,Y
2,label2,N,Y,N
...
我需要在标有Y的“客户”列左侧复制“标签”,在标有N的列左侧没有任何内容(

预期产出:

S.No,Label,Customer1,Customer1,Customer2,Customer2,Customer3,Customer3...
1,label1,label1,Y,"",N,label1,Y
2,label2,"",N,label2,Y,"",N
使用Excel打开时,它将如下所示:

S.No   Label      Customer1   Customer1   Customer2   Customer2   Customer3   Customer3...
   1   label1      label1        Y                       N        label1          Y
   2   label2                    N         label2        Y                        N
最左边的两列(参考编号和原始“标签”列)为常量

最简单的方法是什么?我尝试了以下代码:

use strict;
use warnings;
my $nonIncludesFile = "nonIncludes.csv";
open(my $xfh, "+>", $nonIncludesFile) or warn "Unable to open $nonIncludesFile, $!";
chomp( my $header = <$xfh> );
my @names = split ",", $header;
my @names1;
my @fields;
my @fields1;
for(my $j=0; $j< scalar(@names); $j++)
{
    $names1[$j] = $names[$j];
}
while(<$xfh>)
{
    my $nonIncLine = $_;
    $nonIncLine = chomp($nonIncLine);
    @fields = split ",", $nonIncLine;
    next if $. == 1;                      #skip the first line

    for(my $i = 0; $i < scalar(@fields) -2; $i++)   #Number of "customers" = scalar(@fields) -2
    {
        $fields1[0] = $fields[0];
        $fields1[1] = $fields[1];
        if('Y' eq $fields[ $i + 2 ])
        {
            $fields1[$i+2] = 'Y';
            substr(@fields1, $i + 1, 0, $fields[1]);   #insert the label to the left - HERE
        }
        else
        {
            $fields1[$i+2] = 'N';
            substr(@fields1, $i + 1, 0, "");
        }
    }
}

print $xfh @names1;
print $xfh @fields1;

close($xfh);
使用严格;
使用警告;
my$nonIncludesFile=“nonIncludes.csv”;
打开(我的$xfh,“+>”,$nonIncludesFile)或警告“无法打开$nonIncludesFile,$!”;
chomp(我的$header=);
my@names=split“,”,$header;
我的@names1;
我的@fields;
我的@fields1;
对于(my$j=0;$j<标量(@name);$j++)
{
$names1[$j]=$names[$j];
}
while()
{
我的$noncline=$\;
$noncline=chomp($noncline);
@字段=拆分“,”,$noncline;
下一步如果$.==1;#跳过第一行
对于(我的$i=0;$i<标量(@fields)-2;$i++)#客户数=标量(@fields)-2
{
$fields1[0]=$fields[0];
$fields1[1]=$fields[1];
if('Y'相等于$fields[$i+2])
{
$fields1[$i+2]='Y';
substr(@fields1,$i+1,0,$fields[1])#将标签插入左侧-此处
}
其他的
{
$fields1[$i+2]='N';
substr(@fields1,$i+1,0,”);
}
}
}
打印$xfh@names1;
打印$xfh@fields1;
收盘价($xfh);
但是,这会导致在标有“HERE”的行中出现“字符串外的substr”


我做错了什么?还有什么更简单(更好)的方法吗?

发布一些可用的测试数据总是比写一个类似这样的问题要好得多

但是,您的数据似乎没有带引号的字段或转义字符,因此您可以使用
split
join
来处理CSV数据

下面是一个满足您需求的示例Perl程序。示例输出按原样使用数据。每行数据都必须向后处理,以便插入不会影响尚未处理的元素的索引

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

while ( <DATA> ) {

    chomp;
    my @fields = split /,/;

    for ( my $i = $#fields; $i > 1; --$i ) {

        my $newval = 
            $. == 1               ? $fields[$i] :
            lc $fields[$i] eq 'y' ? $fields[1] :
            '';

        splice @fields, $i, 0, $newval;
    }

    say join ',', @fields;
}

__DATA__
S.No,Label,Customer1,Customer2,Customer3...
1,label1,Y,N,Y
2,label2,N,Y,N

也许是这样的

#!/usr/bin/perl

use strict;
use warnings;

#read the header row
chomp( my ( $sn, $label, @customers ) = split( /,/, <DATA> ) );
#double the 'customers' column headings (one is suffixed "_label")
print join( ",", $sn, $label, map { $_ . "_label", $_ } @customers ), "\n";

#iterate data
while (<DATA>) {
   #strip trailing linefeed
   chomp;
   #extract fields with split - note breaks if you've quoted commas inline. 
   my ( $sn, $label, @row ) = split /,/;
   print "$sn,$label,";
   #iterate Y/N values, and either prints "Y" + label, or anything else + blank. 
   foreach my $value (@row) {
      print join( ",", $value eq "Y" ? $label : "", $value ),",";
   }
   print "\n";
}


__DATA__
S.No,Label,Customer1,Customer2,Customer3
1,label1,Y,N,Y
2,label2,N,Y,N
#/usr/bin/perl
严格使用;
使用警告;
#读取标题行
chomp(my($sn,$label,@customers)=拆分(/,/,);
#将“客户”列标题加倍(其中一个后缀为“_标签”)
打印联接(“,”,$sn,$label,映射{$\.\u label”,$\}@customers),“\n”;
#迭代数据
而(){
#带尾送料
咀嚼;
#如果您在内联中引用了逗号,则提取带有分隔符的字段。
我的($sn,$label,@row)=拆分/,/;
打印“$sn,$label”;
#迭代Y/N值,然后打印“Y”+标签或任何其他+空白的内容。
foreach我的$value(@row){
打印联接(“,”,$value eq“Y”?$label:”,$value),“,”;
}
打印“\n”;
}
__资料__
编号、标签、客户1、客户2、客户3
1,标签1,Y,N,Y
2,标签2,N,Y,N

假定在字段中没有任何果树特殊字符(例如逗号),因为如果您这样做,它将中断,并且您可能需要考虑<代码>文本::CSV < /代码>。p> 您的示例不存在没有带Y的客户的情况。因为只有一个标签列,所以它引用哪个客户列?请回答您的问题,指定要求并添加预期输出。另外,请将您的代码改为

使用strict
使用warnings
。这个问题与有什么不同?我在这里指的是一个特定的问题,涉及哈希数组的语法和语义错误。除了CSV文件中的数据相同外,它与这个问题还有什么相似之处?请原谅我的无知。这感觉像是一个XY问题。我不会完全否认这一点。你可能是对的。我可能已经掉进了那个陷阱——我会设法找到一条出路,并在可能的时候进行相关的编辑。在此之前,任何建议都将不胜感激!列表作业很好
split/,/
split“,”
您的解决方案不会产生预期的输出。我遗漏了什么吗?后面的逗号。我选择将空字段完全保留为空,而不是空字符串,因为我很确定Excel不会在意。拆分的两种模式有什么区别?没有两种模式。只是第一个参数被编译为正则表达式模式,并使用斜杠作为分隔符,这是最好的自我文档。想象一下,$string生成一个空列表,除非
$string
中有换行符,这正是我需要的。非常感谢。