Perl分裂在第一行停止

时间:2014-10-09 14:07:41

标签: perl file split

编辑:重写示例以使其更清晰

我将数据存入名为 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>>
...

2 个答案:

答案 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;
     

但以下代码非常糟糕:

       open my $fh, "<", "foo" or die $!;
       undef $/; # enable slurp mode
       my $content = <$fh>;
       close $fh;
     由于其他一些模块,可能要从某个文件中读取数据          默认的“行模式”,所以如果我们刚才提供的代码已经存在          执行后,$ /的全局值现在已更改为任何其他代码          在同一个Perl解释器中运行。

希望这有帮助。