检查并更改下一行的值

时间:2015-07-10 12:24:10

标签: bash perl awk sed grep

我有一个这样的文件:

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}/) 
    { 

    } 
    }' 

5 个答案:

答案 0 :(得分:1)

以下内容与.的行匹配,并开始累积变量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 }'

答案 1 :(得分:1)

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

答案 2 :(得分:0)

另一种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;

在处理时建立缓冲区,并根据跟随的数量“刷新”或“丢弃”缓冲区。

答案 3 :(得分:0)

此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

答案 4 :(得分:-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地址或文件结尾,然后检查其中是否有多行,并相应地打印或丢弃该块

LIne by line:

# 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.