[英]Perl - Using an Array on a Config txt file
所以我有一個文本文件,在一行上有四組數據,例如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);
您正在my $document = <FILE>
行中讀取整個文件。
嘗試類似的東西:
my @lines;
open my $file, '<', $configfile or die 'xxx';
while( <$file> ) {
chomp;
push @lines, [ split ]
}
現在@lines
有一個包含所需信息的數組。
(編輯)別忘了失去local $/;
- 這就是讓你立刻讀完整個文件的原因。
首先,您可以使用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;
現在,我將整個數組存儲到數組的單個元素中。
要從參考中恢復原始結構,您需要輸入正確的印記 。 由於這是一個數組,你把@
放在它前面:
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
}
my $document = <FILE>
只讀取第一行。 嘗試使用while
循環。
如果你想一次讀取文件的所有行 - 假設它是一個小文件 - 你可能想要使用File::Slurp
模塊:
use File::Slurp;
my @lines = File::Slurp::read_file($configfile);
foreach my $line (@lines) {
# do whatever
此外,您可以使用CPAN模塊將字符串拆分為字段。
如果它們是單空格分隔的,只需使用標准CSV解析器讀取整個文件(您可以將Text::CSV_XS
配置為使用任何characater作為分隔符)。 示例: 如何使用Perl解析下載的CSV數據?
如果它們被隨機數量的空格分隔,請使用下面的@ massa建議並使用split
函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.