我有一个这样的文件:
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}/)
{
}
}'
答案 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.