【问题标题】:Get Multiple IP addresses from one variable using Perl to print a list使用 Perl 从一个变量中获取多个 IP 地址以打印列表
【发布时间】:2013-11-14 15:01:09
【问题描述】:

我需要脚本来逐行打印出 IP 地址列表以及相应的用户名和电子邮件地址以及国家。如何获取多个 IP 地址来执行命令?我试着做一个循环,但它只显示了一行 IP 地址。我希望我的输出看起来像:

1 | login | emailadd@yahoo.com | 160.79.208.82 | United States
16 | login1 | emailadd@yahoo.com | 61.95.83.10 | Italy
23 | login2 | emailadd@gmail.com | 81.48.63.93 | Australia
36 | login3 | emailadd@yahoo.com | 38.117.170.82 | Japan
51 | login4 | emailadd@gmail.com | 2.233.30.85 | Mexico

这是我的代码:

#!/usr/bin/perl -w
use lib '~/lib';
use strict;
use Net::IPInfoDB;

my $g = Net::IPInfoDB->new;
$g->key(api_key);

my $login = '1 | login | emailadd@yahoo.com | 160.79.208.82
            16 | login1 | emailadd@yahoo.com | 61.95.83.10 
            23 | login2 | emailadd@gmail.com | 81.48.63.93 
            36 | login3 | emailadd@yahoo.com | 38.117.170.82 
            51 | login4 | emailadd@gmail.com | 2.233.30.85';

$login =~ /(\d+\.\d+\.\d+\.\d+)/;

my $city = $g->get_city("$1");
my $addr = $g->get_country("$1");


printf "$login | (%s, %s)\n",
$city->city_name, $addr->country_name;

【问题讨论】:

  • 您不使用数组是否有特殊原因?

标签: perl ip ip-address country


【解决方案1】:

如果你想坚持不使用数组,这里有一个获取 IP 地址的解决方案。

while ($login =~ m/(\d+\.\d+\.\d+\.\d+)/g) {
    print "$1\n";
}

【讨论】:

  • @ikegami 使用$& 是一种不好的做法吗?
  • 感谢这工作,但因以下错误而停止:在 /Library/Perl/5.12/Net/IPInfoDB.pm 第 101 行的字符串 ne 中使用未初始化的值。使用未初始化的值 $_[0] in在 /Library/Perl/5.12/Net/IPInfoDB.pm 第 57 行加入或字符串。无法在 array.pl 第 48 行的未定义值上调用方法“country_name”。也许它无法识别 IP。我怎么也显示 1 |登录 | emailadd@yahoo.com |每行160.79.208.82?非常感谢!
  • 您是否在退出循环之前复制变量? $1 的范围仅在循环内,因此您要么必须在循环内调用 get_cityget_country,要么复制 IP 地址并在循环后遍历它们。
【解决方案2】:

使用/g 查找所有匹配项。

my @ips = /(\d+\.\d+\.\d+\.\d+)/g;

也就是说,您显然想要第四个字段,所以让我们实际这样做,而不是冒险从第三个字段中得到一些东西。

sub trim { my ($s) = @_; $s =~ s/^\s+//; $s =~ s/\s+\z//; $s }

for (split /^/m, $login) {
   chomp;
   my @fields = map trim($_), split /\|/;
   my $ip = $fields[2];
   ...
}

【讨论】:

    【解决方案3】:

    您只会获得一个 IP 地址,因为这正是您在整个 $login 上应用正则表达式 ONCE 所做的事情。

    #we split $login into an array, line-by-line
    my @lines = split("\n",$login);
    for my $line (@lines) {
        #now we iterate through every line one-by-one
        $line =~ /(?<ip>\d+\.\d+\.\d+\.\d+)/;
    
        print $+{"ip"}."\n";
    }
    

    在这里,我们遍历 $login 上的每一行,并为每一行单独应用正则表达式。您可以使用该 ip 做任何您想做的事情,而不是打印 ofc。

    另外我这里用的是named match,这只是我的偏好,你不必使用它。

    【讨论】:

    • 谢谢!它在列表中显示所有 IP 地址。如何让它在 IP 地址旁边显示国家?我实际上希望输出看起来像这样带有换行符(我无法显示) 1 |登录 | emailadd@yahoo.com | 160.79.208.82 |美国
      16 |登录1 | emailadd@yahoo.com | 61.95.83.10 |意大利 23 |登录2 | emailadd@gmail.com | 81.48.63.93 |澳大利亚 36 |登录3 | emailadd@yahoo.com | 38.117.170.82 |日本 51 |登录4 | emailadd@gmail.com | 2.233.30.85 |墨西哥
    • 好吧,而不是 'print $+{"ip"}' 把我的 $country=get_somehow_the_country(); $line .= " | $country";打印 "$line\n";据我所知,您只需要将国家/地区附加到现有行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-04
    • 2020-01-11
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 2018-01-19
    • 2014-05-25
    相关资源
    最近更新 更多