所以我有一个文本文件,在一行上有四组数据,例如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);
答案 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
}
答案 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
函数。