编辑:重写示例以使其更清晰
我将数据存入名为 RTR-shpolicymap_751257S0_126.xxx.xxx.xxx_OUTPUT 的文件中:
751257S0;126.xxx;FastEthernet0;up;up;not set;not set;;
751257S0;126.xxx;BRI0;down;down;not set;not set;;
751257S0;126.xxx;BRI0:1;down;down;not set;not set;;
751257S0;126.xxx;BRI0:2;down;down;not set;not set;;
751257S0;126.xxx;ATM0;up;up;not set;not set;;
751257S0;126.xxx;ATM0.835;up;up;not set;not set;;
perl脚本执行到路由器的SSH连接,当建立连接时,它调用函数 executeCommands 此功能如下所述:
sub executeCommands {
open(SSHCONFIG, "/tech/restools/scripts/mynet/RTR-ssh.conf");
while (<SSHCONFIG>) {
@ligne = split(/;/, $_ );
$listop = $ligne[0];
$listcmd = $ligne[1];
$fileprefix = $ligne[2];
$parsername = $ligne[3];
$parsername =~ s/\s+\z// ;
@cmd = split(/,/, $listcmd);
#Si l'operateur passe en parametre match l'operateur dans le fichier de config - execution des commandes
if ($listop =~ /$operateur/) {
for ($index = 0; $index <= $#cmd; $index++) {
$command = $cmd[$index];
&changeCommand(\$command);
&sendCommand($command, $fileprefix);
}
}
else {
next;
}
配置文件包含:
OBS,9 Cegetel,Altitude;sh policy-map $policyinterface;RTR-shpolicymap;RTR-parser9.pl
现在,我遇到了 changeCommand
功能的麻烦sub changeCommand {
my $arg1 = $_[0];
if ($$arg1=~/^(.*)(\$policyinterface)(.*)/) {
print "recherche de l'interface contenant la policy voice correspondante... \n" ;
$fichier_parser1OUTPUT = `find $WORKINGDIR -type f -name RTR-shipint_\"*$codesite*$ip*OUTPUT\"` ;
@table_fichier_parser1OUTPUT = split(/\n/,$fichier_parser1OUTPUT);
for ($index4 = 0 ; $index4 <= $#table_fichier_parser1OUTPUT ; $index4++) {
$fichierNeeded = $table_fichier_parser1OUTPUT[$index4];
open(DATA,$fichierNeeded) || die ("Erreur d'ouverture de $fichierNeeded\n");
print "file $fichierNeeded have been opened \n";
while (my $lineData=<DATA>) {
print "i am printing this line $lineData \n";
my @lineSplitter = split(/;/, $lineData );
print "3e arg est <<$lineSplitter[2]>>\n";
}
$command = "sh policy-map int " . $interfaceNeeded ;
}
}
}
存在的问题是,当我执行我的脚本时会发生这种情况:
recherche de l'interface contenant la policy voice correspondante...
file /tech/restools/tmp/mynet/RTR-working-dir/RTR-shipint_751257S0_126.108.2.250_OUTPUT have been opened
i am printing this line 751257S0;126.108.2.250;FastEthernet0;up;up;not set;not set;;
3e arg est <<FastEthernet0>>
我的错误在哪里?是因为我在之前的函数中已经使用了 $ _ 吗?
单独测试类似的脚本正在运行......
#!/usr/bin/perl
use strict ;
my $codesite="751257S0" ;
my $ip = "126.xxx.xxx.xxx" ;
my $WORKINGDIR="/tech/restools/tmp/mynet/RTR-working-dir";
my $fichier_parser1OUTPUT = `find $WORKINGDIR -type f -name RTR-shipint_\"*$codesite*$ip*OUTPUT\"` ;
my @table_fichier_parser1OUTPUT = split(/\n/,$fichier_parser1OUTPUT);
for (my $index4 = 0 ; $index4 <= $#table_fichier_parser1OUTPUT ; $index4++) {
my $fichierNeeded = $table_fichier_parser1OUTPUT[$index4];
open(DATA,$fichierNeeded) || die ("Erreur d'ouverture de $fichierNeeded\n");
print "file $fichierNeeded have been opened \n";
while (my $lineData=<DATA>) {
print "i am printing this line $lineData \n";
my @lineSplitter = split(/;/, $lineData );
print "3e arg est <<$lineSplitter[2]>>\n";
}
}
打印
i am printing this line 751257S0;126.108.2.250;FastEthernet0;up;up;not set;not set;;
3e arg est <<FastEthernet0>>
i am printing this line 751257S0;126.108.2.250;BRI0;down;down;not set;not set;;
3e arg est <<BRI0>>
i am printing this line 751257S0;126.108.2.250;BRI0:1;down;down;not set;not set;;
3e arg est <<BRI0:1>>
...
答案 0 :(得分:1)
根据文件fichier.1
中问题的数据,以下代码可以产生您看到的效果:
#!/usr/bin/env perl
use strict;
use warnings;
local $/;
my $fichierNeeded = "fichier.1";
open(DATA,$fichierNeeded) || die ("Erreur d'ouverture de $fichierNeeded\n");
print "Fichier $fichierNeeded est ouvert\n";
while (<DATA>) {
print "Ligne: $_";
my @lineSplitter = split(/;/, $_ );
print "3rd arg is <<$lineSplitter[2]>>\n";
}
这个输出是:
Fichier fichier.1 est ouvert
Ligne: 751257S0;126.xxx;FastEthernet0;up;up;not set;not set;;
751257S0;126.xxx;BRI0;down;down;not set;not set;;
751257S0;126.xxx;BRI0:1;down;down;not set;not set;;
751257S0;126.xxx;BRI0:2;down;down;not set;not set;;
751257S0;126.xxx;ATM0;up;up;not set;not set;;
751257S0;126.xxx;ATM0.835;up;up;not set;not set;;
3rd arg is <<FastEthernet0>>
如果省略local $/;
,则输出为:
Fichier fichier.1 est ouvert
Ligne: 751257S0;126.xxx;FastEthernet0;up;up;not set;not set;;
3rd arg is <<FastEthernet0>>
Ligne: 751257S0;126.xxx;BRI0;down;down;not set;not set;;
3rd arg is <<BRI0>>
Ligne: 751257S0;126.xxx;BRI0:1;down;down;not set;not set;;
3rd arg is <<BRI0:1>>
Ligne: 751257S0;126.xxx;BRI0:2;down;down;not set;not set;;
3rd arg is <<BRI0:2>>
Ligne: 751257S0;126.xxx;ATM0;up;up;not set;not set;;
3rd arg is <<ATM0>>
Ligne: 751257S0;126.xxx;ATM0.835;up;up;not set;not set;;
3rd arg is <<ATM0.835>>
由于您没有给我们一个可用的代码片段(循环不完整,甚至),并且您的代码不必要地让我们在目录等上运行find
命令,我们无法重现您的环境足够好。
正如我在评论中提到的,您需要了解如何创建MCVE(Minimal, Complete, Verifiable Example)或SSCCE(Short, Self-Contained, Correct Example)。这是两个相同基本思想的名称(和两个描述)。我提供的代码接近于MCVE或SSCCE(除非它不能再现您的问题)。
还要注意一些基本的调试技巧。打印出刚刚读取的数据是发现问题的最基本方法。在第一个示例输出中,整个文件立即进入内存。如果$/
的设置对您的代码隐藏(某人在您调用的子例程中不小心),这可能是非常宝贵的。我还分隔匹配的字段(用双角括号括起来),这样我就可以更容易地看到数据中是否有奇怪的字符。如果您不确定发生了什么,首先应该添加一些打印语句来打印您正在处理的内容。
答案 1 :(得分:1)
继Jonathan的回答之后
以下是来自perldoc perlvar
的相关部分,其中讨论了可以在您的计划中发生的事情
在大多数情况下你想要 在更改之前将这些变量[如$ /]本地化,因为如果不这样做,那么 更改可能会影响依赖于默认值的其他模块 您已更改的特殊变量。这是正确的 一次读取整个文件的方法:
open my $fh, "<", "foo" or die $!; local $/; # enable localized slurp mode my $content = <$fh>; close $fh;
但以下代码非常糟糕:
由于其他一些模块,可能要从某个文件中读取数据 默认的“行模式”,所以如果我们刚才提供的代码已经存在 执行后,$ /的全局值现在已更改为任何其他代码 在同一个Perl解释器中运行。open my $fh, "<", "foo" or die $!; undef $/; # enable slurp mode my $content = <$fh>; close $fh;
希望这有帮助。