Perl:使用数组列表以选择特定的列

时间:2018-07-11 15:37:33

标签: arrays perl

我有一个python脚本,正在读取数据并将仅特定的列输出到文件中。

我想在Perl中做同样的事情。 我已经在Perl(下面的脚本)中做到了这一点,但无法像在Python中那样使用选择器来使用数组。

此处嵌入了DATA的脚本

#!/usr/bin/python

from StringIO import StringIO

path = "/tmp/log.csv"

__DATA__ = '''
20180704150930|rtsp|645645643|30193|211|KLM|KLM00SD624817.ts|172.30.16.34|127299264|VERB|01780000|21103|277|server01|OK
20180704150931|api|456456546|30130|234|VC3|VC300179201139.ts|172.30.16.138|192271838|VERB|05540000|23404|414|server01|OK
20180704150931|api|465456786|30154|443|BAD|BAD004416550.ts|172.30.16.50|280212202|VERB|04740000|44301|18|server01|OK
20180704150931|api|5437863735|30157|383|VSS|VSS0011062009.ts|172.30.16.66|312727922|VERB|05700000|38303|381|server01|OK
20180704150931|api|3453432|30215|223|VAE|VAE00TF548197.ts|172.30.16.74|114127126|VERB|05060000|22305|35|server01|OK
20180704150931|api|312121|30044|487|BOV|BOVVAE00549424.ts|172.30.16.58|69139448|VERB|05300000|48708|131|server01|OK
20180704150931|rtsp|453432123|30127|203|GZD|GZD0900032066.ts|172.30.16.58|83164150|VERB|05460000|20303|793|server01|OK
20180704150932|api|12345348|30154|465|TYH|TYH0011224259.ts|172.30.16.50|279556843|VERB|04900000|46503|241|server01|OK
20180704150932|api|4343212312|30154|326|VAE|VAE00TF548637.ts|172.30.16.3|28966797|VERB|04740000|32601|969|server01|OK
20180704150932|api|312175665|64530|305|TTT|TTT000000011852.ts|172.30.16.98|47868183|VERB|04740000|30501|275|server01|OK
'''

selector = [0, 3, 5, 7]

__DATA__ = StringIO(__DATA__)
with    open(path + ".py.txt", "w") as output:
        for line in __DATA__:
                line = line.rstrip( "\r\t\n" )
                if not line.strip(): continue  # skip the empty line
                columns = line.split("|")
                newColumns = [ columns[i] for i in selector ]
                output.write("|".join(newColumns) + "\n")
                print ("|".join(newColumns))

问题

因此,使用Perl脚本,我得到了一个类似Python的数组 在我的脚本上,我没有循环使用数组 我直接做$ tab [0]等... 我不知道如何使用数组列表 我想改用@list

在Perl中有相同的代码

#!/usr/bin/perl
use strict;
use warnings;
use autodie;

my $path = "/tmp/log.csv";
my @list = (0, 3, 5, 7);

open(OUT, ">", $path . ".pl.txt");
while (<DATA>) {
        chomp;
        my @tab = split(/\|/, $_);
        my $record = join('|', $tab[0], $tab[3], $tab[5], $tab[7]);
        print $record, "\n";
        print OUT $record, "\n";
}

close(OUT);


__DATA__
20180704150930|rtsp|645645643|30193|211|KLM|KLM00SD624817.ts|172.30.16.34|127299264|VERB|01780000|21103|277|server01|OK
20180704150931|api|456456546|30130|234|VC3|VC300179201139.ts|172.30.16.138|192271838|VERB|05540000|23404|414|server01|OK
20180704150931|api|465456786|30154|443|BAD|BAD004416550.ts|172.30.16.50|280212202|VERB|04740000|44301|18|server01|OK
20180704150931|api|5437863735|30157|383|VSS|VSS0011062009.ts|172.30.16.66|312727922|VERB|05700000|38303|381|server01|OK
20180704150931|api|3453432|30215|223|VAE|VAE00TF548197.ts|172.30.16.74|114127126|VERB|05060000|22305|35|server01|OK
20180704150931|api|312121|30044|487|BOV|BOVVAE00549424.ts|172.30.16.58|69139448|VERB|05300000|48708|131|server01|OK
20180704150931|rtsp|453432123|30127|203|GZD|GZD0900032066.ts|172.30.16.58|83164150|VERB|05460000|20303|793|server01|OK
20180704150932|api|12345348|30154|465|TYH|TYH0011224259.ts|172.30.16.50|279556843|VERB|04900000|46503|241|server01|OK
20180704150932|api|4343212312|30154|326|VAE|VAE00TF548637.ts|172.30.16.3|28966797|VERB|04740000|32601|969|server01|OK
20180704150932|api|312175665|64530|305|TTT|TTT000000011852.ts|172.30.16.98|47868183|VERB|04740000|30501|275|server01|OK

2 个答案:

答案 0 :(得分:9)

您不能在Perl中将循环构造放入数据结构中。那将是语法错误。

但是您可以使用array slice

my $record = join('|', @tab[0, 3, 5, 7]);

请注意 sigil 如何从$更改为@,因为我们现在返回一个列表。当然,您可以将这四个数字放入循环外定义的另一个数组中,并使用它。

my @indexes = ( 0, 3, 5 );
my @slice =  @array[ @indexes ];

答案 1 :(得分:2)

您可以这样做:

my $record = join('|', @tab[@list]);