0

所以我有一个文本文件,一行中有四组数据,例如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

4 回答 4

1

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

尝试类似:

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

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

(编辑)不要忘记丢失local $/;- 这是让您一次阅读整个文件的原因。

于 2013-06-17T20:22:54.123 回答
1

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

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

更好的是,使用数组:

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

我认为您是在说您需要将每个命令部分数组存储到另一个行数组中。那是对的吗?查看本教程,了解 Perl 文档中可用的参考资料。

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
}

阅读参考教程,了解joinsplit

于 2013-06-17T22:02:35.297 回答
0

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

于 2013-06-17T20:20:16.377 回答
0

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

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

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

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

如果它们是单空格分隔的,只需使用标准 CSV 解析器读取整个文件(您可以配置Text::CSV_XS为使用任何字符作为分隔符)。此处的示例:如何使用 Perl 解析下载的 CSV 数据?

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

于 2013-06-17T20:24:22.253 回答