Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 如何在perl中使用split函数来完成awk的工作_Regex_Perl_Awk - Fatal编程技术网

Regex 如何在perl中使用split函数来完成awk的工作

Regex 如何在perl中使用split函数来完成awk的工作,regex,perl,awk,Regex,Perl,Awk,我正在用perl编写一个脚本,我希望尽可能避免使用外部命令,如awk、tr等。 这是我在脚本内部使用反勾号运行的命令: my @arr = `$cmd | tr " " "\n" | xargs -n1 host | awk '{print $4}'` 这是带有outawk'{print 4$}的输出: $fileserver has address 10.90.207.59 $fileserver has address 10.90.207.34 $fileserver has addres

我正在用perl编写一个脚本,我希望尽可能避免使用外部命令,如awk、tr等。 这是我在脚本内部使用反勾号运行的命令:

my @arr = `$cmd | tr " " "\n" | xargs -n1 host | awk '{print $4}'`
这是带有out
awk'{print 4$}
的输出:

$fileserver has address 10.90.207.59
$fileserver has address 10.90.207.34
$fileserver has address 10.90.207.56
$fileserver has address 10.90.207.67
这是带有
awk'{print 4$}
的输出:

10.90.207.59
10.90.207.34
10.90.207.56
10.90.207.67
我希望每个IP都位于阵列中一个单独的单元中。
如何当前使用perl函数(可能是split或map),而不是简单地使用awk和tr?

。默认情况下,
split
的工作原理与
awk
类似。因此:

my @arr = split;
print $arr[3]; #note - arrays start at zero. 
然而,perl通常也可以在文件句柄上逐行运行,并且
拆分
会得到您不想要的东西

您可以:

#!/usr/bin/perl
use strict;
use warnings;

while (<DATA>) {
   my ($ip) = (split)[3];
   print $ip, "\n";
   #or push it. 
}

__DATA__
$fileserver has address 10.90.207.59
$fileserver has address 10.90.207.34
$fileserver has address 10.90.207.56
$fileserver has address 10.90.207.67
#/usr/bin/perl
严格使用;
使用警告;
而(){
我的($ip)=(分割)[3];
打印$ip,“\n”;
#或者推它。
}
__资料__
$fileserver的地址为10.90.207.59
$fileserver的地址为10.90.207.34
$fileserver的地址为10.90.207.56
$fileserver的地址为10.90.207.67
但是如果你想找一件东西:

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my @ips = map { (split)[3] } <DATA>;

print Dumper \@ips;


__DATA__
$fileserver has address 10.90.207.59
$fileserver has address 10.90.207.34
$fileserver has address 10.90.207.56
$fileserver has address 10.90.207.67
#/usr/bin/perl
严格使用;
使用警告;
使用数据::转储程序;
my@ips=map{(split)[3]};
打印转储程序\@ips;
__资料__
$fileserver的地址为10.90.207.59
$fileserver的地址为10.90.207.34
$fileserver的地址为10.90.207.56
$fileserver的地址为10.90.207.67
我们在列表上下文中阅读
,因此它返回整个内容-一次一个元素进行映射


然后在
映射中
我们将每个元素拆分,并抓取元素
3
$4
,以awk术语)

用于类似的perl一行程序

perl -nae 'print "$F[3]\n"' input.txt
-n
对文件进行循环


-a
自动拆分模式。默认情况下,使用空格分割。存储在
@F
中的输出。所以我使用第三个索引来打印ip地址。在perl索引中,从0开始,如果知道所需字段是最后一列,则可以使用从末尾向后计数的索引:

my $ip = (split)[-1];
在单行程序的情况下,使用
-a
开关使Perl将行拆分为
@F
数组(
-n
while(){…}
围绕
-e
的参数进行包装,
-l
为每个
打印
添加新行(请参阅)):

然而,由于您没有被awk困住,所以不必这样做。您可能可以在Perl中完成大部分工作,而无需管道。以下是您开始的内容:

my @arr = `$cmd | tr " " "\n" | xargs -n1 host | awk '{print $4}'`
它看起来像是
$cmd
在一行中生成一组主机名。使用
tr
将空格转换为换行符,然后在每行上运行
host
。对于每个
主机
输出,您获取地址

您可以在单个Perl程序中完成此操作:

 use v5.24;

 use Socket;        # core module
 use Net::hostent;  # core module

 my $cmd = ...;
 foreach my $host ( `$cmd` ) {
      chomp( $host );
      my @addresses = 
          map { inet_ntoa($_) } 
          gethostbyname($host)->addr_list->@*;
      say join "\n", @addresses;
     }
使用列表上下文中的倒勾,Perl将命令的输出分成几行。Perl附带了核心模块和

我已经使用了v5.24的非常好的特性,
->@*
,它将数组引用从
addr\u list
转换为
map
可以使用的常规列表


无论您在
$cmd
中输入什么,都需要小心。我在本书的“安全”一章中详细讨论了这一点。您还可以在文档中找到一些内容。

借助模块中的
inet\u aton
inet\u ntoa
,您可以非常简单地用Perl完成整个过程,除了
$cmd
之外,因为您没有告诉我们这是什么

看起来您的
$cmd
返回一行或多行主机名,以空格分隔,因此我在这里使用了
echo
命令来模拟它。我还使用了
Data::Dump
来显示
@地址的最终内容

use strict;
use warnings 'all';

use Socket;

my $cmd = 'echo www.amazon.co.uk www.perl.com www.stackoverflow.com';

my $cmd_output = `$cmd`;
my @addresses = map { name_to_ip($_) } split ' ', $cmd_output;

use Data::Dump;
dd \@addresses;

sub name_to_ip {

    my ($name) = @_;
    my $add32 = inet_aton($name) or die qq{Unable to convert host name "$name": $!\n};

    inet_ntoa($add32);
}
输出
输入和期望的输出?地址总是IPv4吗?太好了,谢谢,关于“tr”命令,我能做些什么吗?是的。但我不会这样做,因为这一位正在使用
xargs
运行多个命令,而我只是在
perl
中一次运行一个命令。同样感谢您!非常感谢您的详细回答!
use strict;
use warnings 'all';

use Socket;

my $cmd = 'echo www.amazon.co.uk www.perl.com www.stackoverflow.com';

my $cmd_output = `$cmd`;
my @addresses = map { name_to_ip($_) } split ' ', $cmd_output;

use Data::Dump;
dd \@addresses;

sub name_to_ip {

    my ($name) = @_;
    my $add32 = inet_aton($name) or die qq{Unable to convert host name "$name": $!\n};

    inet_ntoa($add32);
}
["54.239.36.155", "207.171.7.72", "151.101.193.69"]