Perl 将字符串拆分为变量并将输出用作元素

Perl 将字符串拆分为变量并将输出用作元素,perl,Perl,嗯。。我又卡住了。我读过不少类似问题的话题,但没有找到解决我问题的方法。我有一个朋友;分隔的csv文件和第8列($elements[7])的字符串如下:“aaaa;bb;cccc;ddddd;eeee;fffff;gg;”。我尝试的是根据;并将输出捕获到变量。然后在主csv文件中的各自列中使用这些变量 因此,现在文件如下所示: 3d;2f;7j;8k;4s;2b;5g;“aaaa;bb;cccc;DDD;eeee;fffff;gg;”;4g;1a;5g;2g;7h;3d;2f;7j 3c;9k;

嗯。。我又卡住了。我读过不少类似问题的话题,但没有找到解决我问题的方法。我有一个朋友;分隔的csv文件和第8列($elements[7])的字符串如下:“aaaa;bb;cccc;ddddd;eeee;fffff;gg;”。我尝试的是根据;并将输出捕获到变量。然后在主csv文件中的各自列中使用这些变量

因此,现在文件如下所示:

3d;2f;7j;8k;4s;2b;5g;“aaaa;bb;cccc;DDD;eeee;fffff;gg;”;4g;1a;5g;2g;7h;3d;2f;7j 3c;9k;5l;4g;1a;5g;3d;“aaaa;bb;cccc;DDD;eeee;fffff;gg;”;4g;1a;5g;2g;7h;3d;2f;7j 4g;1a;5g;2g;7h;3d;8k;“aaaa;bb;cccc;DDD;eeee;fffff;gg;”;3d;2f;7j;8k;4s;2b;4g;1a

我希望它像:

3d;2f;7j;8k;4s;2b;5g;4g;1a;5g;2g;7h;3d;2f;7j;aaaa;bb;中交;ddd;eeee;fffff;游戏打得好 3c;9k;5l;4g;1a;5g;3d;4g;1a;5g;2g;7h;3d;2f;7j;aaaa;bb;中交;ddd;eeee;fffff;游戏打得好 4g;1a;5g;2g;7h;3d;8k;3d;2f;7j;8k;4s;2b;4g;1a;aaaa;bb;中交;ddd;eeee;fffff;gg

这是我一直在尝试的代码。我知道。。太可怕了!但我希望有人能帮我

use strict;
use warnings;

my $inputfile  = shift || die "Give files\n";
my $outputfile = shift || die "Give output\n";

open my $INFILE,  '<', $inputfile   or die "In use / Not found :$!\n";
open my $OUTFILE, '>', $outputfile  or die "In use :$!\n";

while (<$INFILE>) {
  s/"//g;
  my @elements = split /;/, $_;

    my ($varA, $varB, $varC, $varD, $varE, $varF, $varG, $varH) split (';', $elements[10]);
        $elements[16] = $varA;
        $elements[17] = $varB;
        $elements[18] = $varC;
        $elements[19] = $varD; 
        $elements[20] = $varE;
        $elements[21] = $varF;
        $elements[22] = $varG;
        $elements[23] = $varH;

my $output_line = join(";", @elements);
print $OUTFILE $output_line;
}

close $INFILE;
close $OUTFILE;

exit 0;
使用严格;
使用警告;
my$inputfile=shift | | die“Give files\n”;
my$outputfile=shift | | die“给出输出\n”;
打开我的$infle、、$outputfile或die“正在使用:$!\n”;
而(){
s/“//g;
my@elements=split/;/,$;
我的($varA,$varB,$varC,$varD,$varE,$varF,$varG,$varH)拆分(“;”,$elements[10]);
$elements[16]=$varA;
$elements[17]=$varB;
$elements[18]=$varC;
$elements[19]=$varD;
$elements[20]=$varE;
$elements[21]=$varF;
$elements[22]=$varG;
$elements[23]=$varH;
我的$output_line=join(“;”,@elements);
打印$OUTFILE$输出线;
}
关闭$infle;
关闭$OUTFILE;
出口0;
我也对我的语句感到困惑,它不应该是可能的,对吗?我的意思是$vars在一个封闭的部分中,所以不可能将它们写入$elements

编辑

以下是我根据TLP的建议调整代码的方式:

use strict;
use warnings;
use Text::CSV;

my $inputfile  = shift || die "Give files\n";
my $outputfile = shift || die "Give output\n";

open my $INFILE,  '<', $inputfile   or die "In use / Not found :$!\n";
open my $OUTFILE, '>', $outputfile  or die "In use :$!\n";

my $csv = Text::CSV->new({  # create a csv object
    sep_char => ";",    # delimiter
    eol => "\n",        # adds newline to print
});

while (my $row = $csv->getline($INFILE)) {      # $row is an array ref
my $line = splice(@$row, 10, 1);            # remove 8th line
$csv->parse($line);                         # parse the line
push @$row, $csv->fields();                 # push newly parsed fields onto       main array
$csv->print($OUTFILE, $row);
}

close $INFILE;
close $OUTFILE;

exit 0;
使用严格;
使用警告;
使用Text::CSV;
my$inputfile=shift | | die“Give files\n”;
my$outputfile=shift | | die“给出输出\n”;
在使用中打开我的$infle、、$outputfile或die:$\n”;
my$csv=Text::csv->new({#创建一个csv对象
sep_char=>“;”,#分隔符
eol=>“\n”,#在打印时添加换行符
});
而(my$row=$csv->getline($infle)){#$row是一个数组引用
my$line=拼接(@$row,10,1)#拆下第8行
$csv->parse($line)#解析该行
push@$row,$csv->fields();#将新解析的字段推送到主数组上
$csv->打印($OUTFILE,$row);
}
关闭$infle;
关闭$OUTFILE;
出口0;

您应该使用CSV模块,例如解析您的数据。下面是一个简单的示例,说明如何进行解析。您可以用自己的文件句柄替换我在下面使用的文件句柄

use strict;
use warnings;
use Text::CSV;

my $csv = Text::CSV->new({     # create a csv object
        sep_char => ";",   # delimiter
        eol => "\n",       # adds newline to print
    });

while (my $row = $csv->getline(*DATA)) {   # $row is an array ref
    my $line = splice(@$row, 7, 1);   # remove 8th line
    $csv->parse($line);               # parse the line
    push @$row, $csv->fields();       # push newly parsed fields onto main array
    $csv->print(*STDOUT, $row);
}

__DATA__
3d;2f;7j;8k;4s;2b;5g;"aaaa;bb;cccc;ddddd;eeee;fffff;gg;";4g;1a;5g;2g;7h;3d;2f;7j
3c;9k;5l;4g;1a;5g;3d;"aaaa;bb;cccc;ddddd;eeee;fffff;gg;";4g;1a;5g;2g;7h;3d;2f;7j
4g;1a;5g;2g;7h;3d;8k;"aaaa;bb;cccc;ddddd;eeee;fffff;gg;";3d;2f;7j;8k;4s;2b;4g;1a
输出:

3d;2f;7j;8k;4s;2b;5g;4g;1a;5g;2g;7h;3d;2f;7j;aaaa;bb;cccc;ddddd;eeee;fffff;gg;
3c;9k;5l;4g;1a;5g;3d;4g;1a;5g;2g;7h;3d;2f;7j;aaaa;bb;cccc;ddddd;eeee;fffff;gg;
4g;1a;5g;2g;7h;3d;8k;3d;2f;7j;8k;4s;2b;4g;1a;aaaa;bb;cccc;ddddd;eeee;fffff;gg;

我真的应该看看perl中的Text::CSV模块!这需要我花一些时间来弄清楚..但是我如何将它与代码的用户输入/输出文件部分结合起来?因为真正的文件不是3行而是200/400k行。@27就像我说的,你可以用你来替换文件句柄
*数据
*和
*标准输出
r own,例如
$infle
$OUTFILE
。它起作用了。除了我得到的唯一输出是前两行之外。如果Text::CSV发现一行无法解析,while循环可能会中断。如果您的输入不规则,您可以使用常规循环,而不是使用
$CSV->parse
$cvs->fields
,尽管这会导致错误性能下降。如果性能很重要,您可能还想使用XS版本,Text::csvxs。不,性能不是问题。但是,找出如何从常规循环开始是个问题。我恐怕不知道如何做。可以告诉我如何做吗?