【问题标题】:How to Split String with 2 Foreach Perl如何使用 2 Foreach Perl 拆分字符串
【发布时间】:2026-02-14 14:25:02
【问题描述】:

您好,我有一个连接到 cisco 路由器的 perl 脚本

如果不这样拆分的实际输出

显示int desc 接口状态协议说明 Gi1/0/0 up TRUNK ME-A-JKT-TAN 5/2/1 u/ Service VPN-IP (Support QoS) Gi1/0/0.23 up up VPNIP TIGARAKSA SATRIA BSD,TANGERANG CID 20490023 TENOSS 47086151509200818077

然后我像这样将我的代码放入这个脚本中

my @output1 = split(/\s{2,}/, $output);

foreach my $output2 (@output1) {
 $output3="$output2%";
 my @output4 = split(/\s{2,}/, $output3);
  foreach my $output5 (@output4) {
   print "$output5#"
 }
}

为什么会这样打印出来

显示int desc 接口%#状态%#协议说明 Gi1/0/0%#up%#up%#TRUNK ME-A-JKT-TAN 5/2/1 u/服务VPN-IP(支持QoS) Gi1/0/0.23%#up%#up%#VPNIP TIGARAKSA SATRIA BSD,TANGERANG CID 20490023 TENOSS 47086151509200818077

我想这样打印出来

show int desc#Interface%Status%Protocol%Description#Gi1/0/0%up%up%TRUNK ME-A-JKT-TAN 5/2/1 u/ Service VPN-IP (Support QoS)#Gi1/0/ 0.23%up%up%VPNIP TIGARAKSA SATRIA BSD,TANGERANG CID 20490023 TENOSS 47086151509200818077#

我想要 2 个或更多的空格,用 % 分隔,/n 用 # 分隔 感谢您的帮助

【问题讨论】:

    标签: perl shell cisco


    【解决方案1】:

    也许是因为你没有chomped 你的台词?此外,您将 #% 添加到具有嵌套 for 循环的每一行。您的第二个拆分语句与第一个相同,是什么让您认为它有什么作用?

    如果您只想替换空格和换行符,为什么不这样做呢?

    $output =~ s/\n+/#/g;
    $output =~ s/\s{2,}/%/g;
    print $output;
    

    此外,您应该知道将变量命名为 $output2$output3 ... $output5 是一种可怕的做法。

    【讨论】:

    • 感谢先生,它的工作就像一个魅力,对不起,我是 perl 的新手 :)
    • 不客气。您应该知道解析固定宽度数据的方法比split 更好。例如,查看 substrunpack 的文档。
    【解决方案2】:

    有点挑战,但试试这个。它将数据放入哈希数组中。输出为Data::Dumper::Dumper。将其替换为您选择的格式。

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    # --------------------------------------
    use Data::Dumper;
    
    # Make Data::Dumper pretty
    $Data::Dumper::Sortkeys = 1;
    $Data::Dumper::Indent   = 1;
    
    # Set maximum depth for Data::Dumper, zero means unlimited
    local $Data::Dumper::Maxdepth = 0;
    
    # --------------------------------------
    
    my @Status = ();
    my @field_names = ();
    my $unpack_template = '';
    
    my $in_body = 0;  #TRUE when reading the data
    while( my $line = <DATA> ){
      chomp $line;
    
      if( $in_body ){
        my @fields = unpack( $unpack_template, $line );
    
        # remove trailing spaces
        s{ \s+ \z }{}msx for @fields;
    
        # add a hash to the Status
        my %status = ();
        for my $i ( 0 .. $#field_names ){
          $status{ $field_names[$i] } = $fields[$i];
        }
        push @Status, \%status;
    
      }elsif( $line =~ m{ \A Interface \b }msx ){
    
        # calculate unpack template
        while( length $line ){
          $line =~ s{ \A (\w+) (\s*) }{}msx;
          my $field = $1;
          my $spaces = $2;
    
          $unpack_template .= 'a' . ( length( $field ) + length( $spaces ));
          push @field_names, $field;
        }
    
        # correct the last item to read to end of line
        $unpack_template =~ s{ \d+ \z }{*}msx;
    
        # now reading the body
        $in_body = 1;
      }
    }
    
    print Dumper \@Status;
    
    
    __DATA__
    show int desc
    Interface                      Status         Protocol Description
    Gi1/0/0                        up             up       TRUNK ME-A-JKT-TAN 5/2/1 u/ Service VPN-IP (Support QoS)
    Gi1/0/0.23                     up             up       VPNIP TIGARAKSA SATRIA BSD,TANGERANG CID 20490023 TENOSS 47086151509200818077
    

    【讨论】:

      最近更新 更多