Perl 输出不按数字顺序
我的Perl代码没有从数组中以数字顺序返回输出 我有这个数字数组Perl 输出不按数字顺序,perl,Perl,我的Perl代码没有从数组中以数字顺序返回输出 我有这个数字数组 my @luns = qw/ 393645 393646 393730 393731 393732 393733 414632 433944 /; 我想执行一个命令并通过Perl中的管道读取输出,这样我就可以迭代@luns数组来搜索特定的值 这是通过管道读取的命令的输出 primary-vds0 primary
my @luns = qw/
393645
393646
393730
393731
393732
393733
414632
433944
/;
我想执行一个命令并通过Perl中的管道读取输出,这样我就可以迭代@luns
数组来搜索特定的值
这是通过管道读取的命令的输出
primary-vds0 primary
/dev/dsk/c0txxxxxx393731d0s6
/dev/dsk/c0txxxxxx414632d0s6
/dev/dsk/c0txxxxxx393732d0s6
/dev/dsk/c0txxxxxx393733d0s6
/dev/dsk/c0txxxxxx393645d0s6
/dev/dsk/c0txxxxxx393646d0s6
/dev/dsk/c0txxxxxx393730d0s6
/dev/dsk/c0txxxxxx433944d0s6
这是我的剧本
#!/bin/perl -w
use strict;
my @luns = qw/
393645
393646
393730
393731
393732
393733
414632
433944
/;
open(my $pipe, "ldm ls-services |") or die "Cannot open process: $!";
my $line;
while ( <$pipe> ) {
foreach $line ( @luns ) {
if ( $_ =~ $line ) {
print $_;
}
}
}
您不能只使用两个嵌套循环,因为文件中的记录没有排序。要解决这个问题,您必须将匹配行存储在一个数组中并对该数组进行排序。一个很容易做到的技巧是在每行的开头连接数字。然后,只需使用字符串比较即可对行进行排序:
use strict;
use warnings;
my @luns = qw/
393645
393646
393730
393731
393732
393733
414632
433944
/;
my @result;
while (my $line = <DATA>) {
for (@luns) {
push @result, sprintf("%07d%s", $_, $line) if ($line =~ $_);
}
}
@result = map { substr $_, 7 } sort @result;
print join '', @result;
__DATA__
primary-vds0 primary
/dev/dsk/c0txxxxxx393731d0s6
/dev/dsk/c0txxxxxx414632d0s6
/dev/dsk/c0txxxxxx393732d0s6
/dev/dsk/c0txxxxxx393733d0s6
/dev/dsk/c0txxxxxx393645d0s6
/dev/dsk/c0txxxxxx393646d0s6
/dev/dsk/c0txxxxxx393730d0s6
/dev/dsk/c0txxxxxx433944d0s6
最简单的方法是将命令的所有输出读入内存。通过这种方式,可以对其进行多次搜索,以查看是否有任何
@luns
数组元素出现在输出中
如果对@luns
进行了预排序,则输出顺序相同。我添加了一个sort
调用,以确保它们是正确的,但是如果数字不总是六位数长,那么您还必须使用前导零将它们填充到正确的长度;否则,作为较长LUN的子字符串的较短LUN将引发误报
在这里,我添加了一个测试,以确保如果LUN出现在命令输出中,那么它的前面或后面不能有其他数字。这适用于你的样本数据,但我不能确定它是否普遍正确
如果您有更高版本的List::Util
,则可以使用any
代替first
use strict;
use warnings;
use feature 'say';
use List::Util 'first';
my @luns = sort { $a <=> $b } qw/
393645
393646
393730
393731
393732
393733
414632
433944
/;
my @data = <DATA>;
chomp @data;
for my $lun ( @luns ) {
say $lun if first { /(?<!\d)$lun(?!\d)/ } @data;
}
__DATA__
primary-vds0 primary
/dev/dsk/c0txxxxxx393731d0s6
/dev/dsk/c0txxxxxx414632d0s6
/dev/dsk/c0txxxxxx393732d0s6
/dev/dsk/c0txxxxxx393733d0s6
/dev/dsk/c0txxxxxx393645d0s6
/dev/dsk/c0txxxxxx393646d0s6
/dev/dsk/c0txxxxxx393730d0s6
/dev/dsk/c0txxxxxx433944d0s6
由于$位于foreach循环内,因此它不再是文件的一行,而是数组的一个值。简而言之,
$\u=~$line
与$line=~$line
相同。改为写:while($line=){foreach(@luns){if($line=~$){
也可以使用条件索引($line,$)!=-1
代替$line=~$\ucode>@Casimir et Hippolyte查看我的更新。“你不能只使用两个嵌套循环,因为文件中的记录没有排序”但是,@luns
的内容是经过排序的,因此,如果您在最外层的循环中迭代数组,输出也将被排序。必须有一种方法可以扫描每个LUN的整个输入数据,并且ldm
命令的输出应该足够小,可以将其读入数组。
use strict;
use warnings;
my @luns = qw/
393645
393646
393730
393731
393732
393733
414632
433944
/;
my @result;
while (my $line = <DATA>) {
for (@luns) {
push @result, sprintf("%07d%s", $_, $line) if ($line =~ $_);
}
}
@result = map { substr $_, 7 } sort @result;
print join '', @result;
__DATA__
primary-vds0 primary
/dev/dsk/c0txxxxxx393731d0s6
/dev/dsk/c0txxxxxx414632d0s6
/dev/dsk/c0txxxxxx393732d0s6
/dev/dsk/c0txxxxxx393733d0s6
/dev/dsk/c0txxxxxx393645d0s6
/dev/dsk/c0txxxxxx393646d0s6
/dev/dsk/c0txxxxxx393730d0s6
/dev/dsk/c0txxxxxx433944d0s6
my @result;
while (my $line = <DATA>) {
for (@luns) {
push @result, [ $_, $line ] if ($line =~ $_);
}
}
@result = map { $_->[1] } sort { $a->[0] <=> $b->[0] } @result;
print join '', @result;
use strict;
use warnings;
use feature 'say';
use List::Util 'first';
my @luns = sort { $a <=> $b } qw/
393645
393646
393730
393731
393732
393733
414632
433944
/;
my @data = <DATA>;
chomp @data;
for my $lun ( @luns ) {
say $lun if first { /(?<!\d)$lun(?!\d)/ } @data;
}
__DATA__
primary-vds0 primary
/dev/dsk/c0txxxxxx393731d0s6
/dev/dsk/c0txxxxxx414632d0s6
/dev/dsk/c0txxxxxx393732d0s6
/dev/dsk/c0txxxxxx393733d0s6
/dev/dsk/c0txxxxxx393645d0s6
/dev/dsk/c0txxxxxx393646d0s6
/dev/dsk/c0txxxxxx393730d0s6
/dev/dsk/c0txxxxxx433944d0s6
393645
393646
393730
393731
393732
393733
414632
433944