【问题标题】:Checking and altering value of next line检查和更改下一行的值
【发布时间】:2015-09-29 04:46:13
【问题描述】:

我有一个这样的文件:

1.0.0.2
32
255.0.0.6
0
32.0.191.171
64
32
128.1.1.1
128
64
128
97.4.100.3
32

它应该看起来像这样(该文件包含 IP 和数字。每个 IP 后面应该紧跟一个数字,而不是更多。如果一个 IP 后面跟着两个或多个数字,则 IP 和数字应该被删除):

1.0.0.2
32
255.0.0.6
0
97.4.100.3
32

我用 awk 尝试了一些代码(get line, prev),但不幸的是无法完成。我不知道它是否有帮助,但我认为这段代码应该识别IP:

awk --re-interval '{
    if ($0 ~ /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/) 
    { 

    } 
    }' 

【问题讨论】:

    标签: bash perl awk sed grep


    【解决方案1】:

    使用 sed:

    sed '/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/! { H; $!d; }; x; //!d; /\n.*\n/d' filename
    

    这会将最后找到的 IP 地址及其后面的行保存在保持缓冲区中,直到找到下一个 IP 地址或文件结尾,然后检查其中是否有超过两行并相应地打印或丢弃该块.

    逐行:

    # If there is no IP address in the current line (note the ! after the condition)
    /[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/! {
    
      # append the line to the hold buffer.
      H
    
      # and unless it is the last one, continue with the next line, not printing
      # anything.
      $!d
    }
    
    # We only get here if there was an IP address or this is the last line. Swap in
    # the remembered things from the hold buffer (placing the IP address in the hold
    # buffer at the same time)
    x
    
    # If there's no IP address in the stuff we swapped in (// reattempts the last
    # regex, which is the IP regex, and that there isn't one happens the very first
    # time we get here), discard it.
    //!d
    
    # If there are two newlines in it, discard it also.
    /\n.*\n/d
    
    # Otherwise we drop off here and it is printed.
    

    【讨论】:

    • 非常感谢 - 也为您的详细描述 - 它工作完美!
    【解决方案2】:

    以下匹配行与. 并开始累积变量acc 中的行。其他行通过插入的换行符连接到变量上。最后,或者当一行有. 时,如果acc 变量正好有1 个换行符(即分成2 部分),则打印它。 将您的数据导入其中。

    awk '/\./{ if(split(acc,x,"\n")==2)print acc; acc = $1; next }
             { acc = acc "\n" $0 }
          END{ if(split(acc,x,"\n")==2)print acc }'
    

    【讨论】:

      【解决方案3】:

      perl 方式:

      $/=undef;
      my $str = <DATA>;
      $str =~ s/\d+(?:\.\d+){3}\R(?:\d+\R){2,}//g;
      say $str;
      
      __DATA__
      1.0.0.2
      32
      255.0.0.6
      0
      32.0.191.171
      64
      32
      128.1.1.1
      128
      64
      128
      97.4.100.3
      32
      

      输出:

      1.0.0.2
      32
      255.0.0.6
      0
      97.4.100.3
      32
      

      【讨论】:

        【解决方案4】:

        另一种perl 方法 - 我知道你已经有一个,但这需要一个不同的角度。

        #!/usr/bin/env perl
        use strict;
        use warnings;
        
        my $current_buffer = '';
        my $notip = 0;
        while (<>) {
            if ( my ($ip) = m/^(\d+\.\d+\.\d+\.\d+)$/ ) {
                if ( $notip <= 1 ) { print $current_buffer; }
                $current_buffer = $ip . "\n";
                $notip          = 0;
            }
            else {
                $notip++;
                $current_buffer .= $_;
            }
        }
        
        print $current_buffer if $notip <= 1;
        

        在处理过程中建立一个缓冲区,并根据后面的数字“刷新”或“丢弃”缓冲区。

        【讨论】:

          【解决方案5】:

          这个 Perl 解决方案以不同的方式工作。它一次读取一行输入,并在每次遇到包含点的行时在@blocks 中启动一个新块。其结果是将输入拆分为以 IP 地址开头的行块

          然后打印出恰好有两行的那些累积块

          use strict;
          use warnings;
          
          my @blocks;
          
          while ( <DATA> ) {
              push @blocks, [ ] if /\./;
              push @{ $blocks[-1] }, $_;
          }
          
          for my $block ( @blocks ) {
            print @$block if @$block == 2;
          }
          
          __DATA__
          1.0.0.2
          32
          255.0.0.6
          0
          32.0.191.171
          64
          32
          128.1.1.1
          128
          64
          128
          97.4.100.3
          32
          

          输出

          1.0.0.2
          32
          255.0.0.6
          0
          97.4.100.3
          32
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多