下面的代码工作正常,但我希望在关闭文件后打印$ip
。
use strict;
use warnings;
use POSIX;
my $file = "/tmp/example";
open(FILE, "<$file") or die $!;
while ( <FILE> ) {
my $lines = $_;
if ( $lines =~ m/address/ ) {
my ($string, $ip) = (split ' ', $lines);
print "IP address is: $ip\n";
}
}
close(FILE);
/ tmp / example文件中的示例数据
$cat /tmp/example
country us
ip_address 192.168.1.1
server dell
答案 0 :(得分:2)
此解决方案查找包含ip_address
后跟一些空格和一系列数字和点的第一行
在块中包装搜索会使perl删除词法变量$fh
。因为它是一个文件句柄,该句柄也将自动关闭
请注意,我已使用autodie
来避免明确检查open
电话的状态
此算法将找到ip_address
的第一个次出现并立即停止读取该文件
use strict;
use warnings 'all';
use autodie;
my $file = '/tmp/example';
my $ip;
{
open my $fh, '<', $file;
while ( <$fh> ) {
if ( /ip_address\h+([\d.]+)/ ) {
$ip = $1;
last;
}
}
}
print $ip // 'undef', "\n";
192.168.1.1
答案 1 :(得分:1)
将所有ips存储在一个数组中,然后您将其用于以后的处理。 显示的代码也可以简化很多。这假设一个四个数字的ip和数据,如样本
中所示use warnings;
use strict;
use feature 'say';
my $file = '/tmp/example';
open my $fh, '<', $file or die "Can't open $file: $!";
my @ips;
while (<$fh>) {
if (my ($ip) = /ip_address\s*(\d+\.\d+\.\d+\.\d+)/) {
push @ips, $ip;
}
}
close $fh;
say for @ips;
或者,打开文件后,使用map
my @ips = map { /ip_address\s*(\d+\.\d+\.\d+\.\d+)/ } <$fh>;
此处的文件句柄在列表上下文中读取,由map
强加,因此返回文件中的所有行。 map
中的块依次适用于每个块,map
会返回带有结果的展平列表。
一些注释
使用三个参数open
,它更好
不要将$_
分配给变量。使用词汇使用while (my $line = <$fh>)
您可以使用split
,但此处正则表达式更直接,它允许您分配匹配,以便它是作用域。如果没有匹配,则if
失败并且没有任何内容进入数组
答案 2 :(得分:0)
use warnings;
use strict;
my $file = "test";
my ( $string,$ip);
open my $FH, "<",$file) or die $!;
while (my $lines = <FH>) {
if ($lines =~ m/address/){
($string, $ip) = (split ' ', $lines);
}
}
print "IP address is: $ip\n";
这将为您提供所需的输出。但是在输入文件中多个IP匹配行的情况下会失败,会覆盖最后一个$ ip变量。