[英]Reading data from file into an array to manipulate within Perl script
Perl新手。 我需要弄清楚如何从(:)分隔的文件中读取数组。 然后我可以操纵数据。
下面是'serverFile.txt'文件的示例(只是随机输入#)字段名称:CPU利用率:avgMemory用法:无磁盘
Server1:8:6:2225410
Server2:75:68:64392
Server3:95:90:12806
Server4:14:7:1548700
我想弄清楚如何将每个字段放入适当的数组然后执行函数。 例如,找到具有最少可用磁盘空间的服务器。
我现在的方式设置,我认为不会起作用。 那么如何将每行中的每个元素放入一个数组中?
#!usr/bin/perl
use warnings;
use diagnostics;
use v5.26.1;
#Opens serverFile.txt or reports and error
open (my $fh, "<", "/root//Perl/serverFile.txt")
or die "System cannot find the file specified. $!";
#Prints out the details of the file format
sub header(){
print "Server ** CPU Util% ** Avg Mem Usage ** Free Disk\n";
print "-------------------------------------------------\n";
}
# Creates our variables
my ($name, $cpuUtil, $avgMemUsage, $diskFree);
my $count = 0;
my $totalMem = 0;
header();
# Loops through the program looking to see if CPU Utilization is greater than 90%
# If it is, it will print out the Server details
while(<$fh>) {
# Puts the file contents into the variables
($name, $cpuUtil, $avgMemUsage, $diskFree) = split(":", $_);
print "$name ** $cpuUtil% ** $avgMemUsage% ** $diskFree% ", "\n\n", if $cpuUtil > 90;
$totalMem = $avgMemUsage + $totalMem;
$count++;
}
print "The average memory usage for all servers is: ", $totalMem / $count. "%\n";
# Closes the file
close $fh;
对于这个用例,哈希比数组好得多。
#!/usr/bin/perl
use strict;
use feature qw{ say };
use warnings;
use List::Util qw{ min };
my %server;
while (<>) {
chomp;
my ($name, $cpu_utilization, $avg_memory, $disk_free)
= split /:/;
@{ $server{$name} }{qw{ cpu_utilization avg_memory disk_free }}
= ($cpu_utilization, $avg_memory, $disk_free);
}
my $least_disk = min(map $server{$_}{disk_free}, keys %server);
say for grep $server{$_}{disk_free} == $least_disk, keys %server;
choroba的答案很理想,但我认为你自己的代码可以改进
除非您需要仅在给定版本的Perl中可用的特定功能,否则请勿use v5.26.1
。 请注意,它还启用use strict
,它应该位于您编写的每个Perl程序的顶部
die "System cannot find the file specified. $!"
是错误的:除了“无法找到”之外, open
可能会失败的原因有多种。 你的die
字符串应该包含你试图打开的文件的路径; 失败的原因是$!
不要使用子程序原型:它们不会按照您的想法执行。 sub header() { ... }
应该只是sub header { ... }
声明子程序只是为了稍后调用几行是没有意义的。 将header
的代码放在行中
你显然来自另一种语言。 尽可能晚地用my
声明你的变量。 在这种情况下,只有$count
和$totalMem
必须在while
循环之外声明
当程序退出时,perl将关闭所有打开的文件句柄。 很少需要明确的close
通话,这会使您的代码更加嘈杂
$totalMem = $avgMemUsage + $totalMem
通常写成$totalMem += $avgMemUsage
我希望有所帮助
关于如何将数据存储在数组中的原始问题...
首先,在文件读取循环外初始化一个空数组:
my @servers = ();
然后,在循环中,在解析完数据后,可以将它们作为子数组存储在数组中(结果数据结构是二维数组):
$servers[$count] = [ $name, $cpuUtil, $avgMemUsage, $diskFree ];
请注意,右侧的方括号为服务器的数据块创建子数组,并返回对此新数组的引用。 另外,在左侧,我们只使用$ count的当前值作为@servers数组中的索引,随着值的增加, @ servers数组的大小将自动增长(这称为新元素的自动生成)。 或者,您可以将新元素推送到循环内的@servers数组,如下所示:
push @servers, [ $name, $cpuUtil, $avgMemUsage, $diskFree ];
这样,您明确要求将新元素添加到数组中,并且方括号仍然执行相同的子数组创建。
在任何情况下,最终结果是在完成文件读取循环后,您现在有一个2D数组,您可以在其中访问第一个服务器及其磁盘空闲字段(索引3处的第4个字段),如下所示:
my $df = $servers[0][3];
或者检查循环中的所有服务器以找到最小的可用磁盘:
my $min_s = 0;
for ( my $s = 0; $s < @servers; $s++ ) {
$min_s = $s if ( $servers[$s][3] < $servers[$min_s][3] );
}
print "Server $min_s has least disk free: $servers[$min_s][3]\n";
与@choroba建议一样,您可以将服务器数据片段/字段存储在哈希中,以便您的代码更具可读性。 您仍然可以将您的服务器列表存储在一个数组中,但第二个维度可以是哈希:
$servers[$count] = {
name => $name,
cpu_util => $cpuUtil,
avg_mem_usage => $avgMemUsage,
disk_free => $diskFree
};
因此,您生成的结构将是一个哈希数组。 这里,右边的花括号创建一个新的哈希并返回对它的引用。 所以,你以后可以参考:
my $df = $servers[0]{disk_free};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.