Perl - 在Config txt文件上使用数组

时间:2013-06-17 20:16:54

标签: perl

所以我有一个文本文件,在一行上有四组数据,例如aa bb username password。到目前为止,我已经能够使用子串和索引解析文件的第一行,并将四个中的每一个分配给变量。

我的目标是使用一个数组并选择每一行并将它们分配给四个变量,然后将用户输入的参数与第一个变量相匹配,并使用该正确行中的四个变量。

例如,这将是文本文件:

"aa bb cc dd"
"ee ff gg hh"   

根据用户输入“aa”或“ee”作为参数,它将在代码中使用该行的参数集。

我试图建立一个基本数组,并根据第一个变量的条件,通过它来扼杀它。

这是第一行的四个变量的代码,但正如我所说,这只适用于文本文件的第一行:

local $/;
open(FILE, $configfile) or die "Can't read config file 'filename' [$!]\n";  
my $document = <FILE>; 
close (FILE);  



my $string = $document;
my $substring = " ";

my $Index = index($string, $substring);
my $aa = substr($string, 0, $Index);
my $newstring = substr($string, $Index+1);

my $Index2 = index($newstring, $substring); 
my $bb = substr($newstring, 0, $Index2);
my $newstring2 = substr($newstring, $Index2+1);

my $Index3 = index($newstring2, $substring);
my $cc = substr($newstring2, 0, $Index3);
my $newstring3 = substr($newstring2, $Index3+1);

my $Index4 = index($newstring3, $substring);
my $dd = substr($newstring3, 0, $Index4);

4 个答案:

答案 0 :(得分:1)

您正在my $document = <FILE>行中阅读整个文件。

尝试类似:

my @lines;
open my $file, '<', $configfile or die 'xxx';
while( <$file> ) {
  chomp;
  push @lines, [ split ]
}

现在@lines有一个数组数组,其中包含您需要的信息。

(编辑)不要忘记丢失local $/; - 这就是让你立刻读完整个文件的原因。

答案 1 :(得分:1)

首先,您可以使用split解析整行,而不是在它们上运行索引和子字符串:

my ( $aa, $bb, $cc, $dd ) = split /\s+/, $line;

更好的是,使用数组:

my @array = split /\s+/, $line;

我认为你说你需要将每个命令部分数组存储到另一行数组中。那是对的吗?请查看Perl文档中提供的tutorial on references

Perl有三种不同类型的变量。问题是这些变量的每种类型只存储一个数据。数组和散列可以存储大量数据,但只有一个数据可以存储在散列或数组的每个元素中。

参考文献允许您绕过此限制。引用只是指向另一条数据的指针。例如,如果$line = aa bb cc dd,请执行以下操作:

 my @command_list = split /\s+/ $line;

会给你以下内容:

$command_list[0] = "aa";
$command_list[1] = "bb";
$command_list[2] = "cc";
$command_list[3] = "dd";

您希望将@command_list存储到其他结构中。您需要的是对@command_list的引用。要获得它的引用,你只需在它前面加一个反斜杠:

my $reference = \@command_list;

这可以放在一个数组中:

my @array;
$array[0] = $reference;

现在,我将整个数组存储到数组的单个元素中。

要从参考中恢复原始结构,请输入正确的sigil。由于这是一个数组,因此您将@放在它前面:

my @new_array = @{ $reference };

如果您想要引用中的第一项而不必将其传输到另一个数组中,您可以简单地将@{ $reference }视为数组本身:

${ $reference }[0] = "aa";

或者,使用魔术->,这使语法更清晰:

$reference->[0] = "aa";

完成教程。这将有助于您了解参考的全部功能,以及如何使用它们。你的程序看起来像这样:

use strict;
use warnings;
use feature qw(say);  #Better print that print
use autodie;          #Kills your program if the file can't be open

my $file = [...]   #Somehow get the file you're reading in...
open my $file_fh, "<", $file;
my @command_list;
while ( my $line = <$file_fh> ) {
    chomp $line;
    my @line_list = split /\s+/, $line;
    push @command_list, \@line_list;
}

请注意,push @command_list, \@line_list;正在将对一个数组的引用推送到另一个数组。你怎么把它拿回来的?简单:

for my $cmd_line_ref ( @command_list ) {
    my $command = $cmd_line_ref->[0];    #This is the first element in your command
    next unless $command eq $user_desires;  # However you figure out what the user wants
    my $line = join " ", @{ $cmd_line_ref } #Rejoins your command line once again
    ???   #Profit
}

阅读tutorial on references,了解joinsplit

答案 2 :(得分:0)

my $document = <FILE>仅在第一行读取。尝试使用while循环。

答案 3 :(得分:0)

如果你想一次读取文件的所有行 - 假设它是一个小文件 - 你可能想要使用File::Slurp模块:

use File::Slurp;
my @lines = File::Slurp::read_file($configfile);

foreach my $line (@lines) {
    # do whatever

此外,您可以使用CPAN模块将字符串拆分为字段。

如果它们是单空格分隔的,只需使用标准CSV解析器读取整个文件(您可以配置Text::CSV_XS以使用任何字符作为分隔符)。示例:How can I parse downloaded CSV data with Perl?

如果它们被随机数量的空格分开,请使用下面的@ massa建议并使用split函数。

相关问题