0

そのため、1 行に 4 セットのデータを含むテキスト ファイルがありますaa bb username password。これまでのところ、部分文字列とインデックスを使用してファイルの最初の行を解析し、4 つのそれぞれを変数に割り当てることができました。

私の目標は、配列を使用して各行をむさぼり食って 4 つの変数に割り当て、ユーザーが入力した引数を最初の変数に一致させ、その正しい行で 4 つの変数を使用することです。

たとえば、これはテキスト ファイルです。

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

また、ユーザーが引数として「aa」または「ee」のどちらを入力したかに応じて、その行の引数のセットがコードで使用されます。

基本的に、最初の変数の条件に基づいて、基本的な配列を取得してむさぼり食おうとしています。

最初の行の 4 つの変数のコードを次に示しますが、前述のように、これはテキスト ファイルの最初の行でのみ機能します。

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 ( $aa, $bb, $cc, $dd ) = split /\s+/, $line;

さらに良いことに、配列を使用します。

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

コマンド部分の各配列を別の行配列に格納する必要があると言っていると思います。あれは正しいですか?Perl ドキュメントで利用可能な参照に関するこのチュートリアルを見てください。

Perl には 3 種類の変数があります。問題は、これらの変数の各タイプが 1 つのデータしか格納しないことです。配列とハッシュは大量のデータを格納できますが、ハッシュまたは配列の各要素に格納できるデータは 1 つだけです。

参照を使用すると、この制限を回避できます。参照は、別のデータへの単なるポインタです。たとえば、$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;

今、配列全体を配列の 1 つの要素に格納しています。

参照から元の構造に戻るには、正しい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
}

参照 に関するチュートリアルを読み、joinとについて学びsplitます。

于 2013-06-17T22:02:35.297 に答える
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 に答える
0

ファイルのすべての行を一度に読みたい場合 (ファイルが小さいと仮定して)、次のFile::Slurpモジュールを使用することをお勧めします。

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

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

また、CPAN モジュールを使用して文字列をフィールドに分割することもできます。

シングルスペースで区切られている場合は、標準の CSV パーサーを使用してファイル全体を読み取るだけです (Text::CSV_XS任意の文字を区切り文字として使用するように構成できます)。例:ダウンロードした CSV データを Perl で解析するにはどうすればよいですか?

それらがランダムな量の空白で区切られている場合は、以下の @massa のアドバイスを使用し、split関数を使用してください。

于 2013-06-17T20:24:22.253 に答える