如何在Perl中将4个连续的空行压缩成一行

时间:2012-09-06 09:49:01

标签: perl

我正在编写一个Perl脚本来读取日志,以便在看到任何连续的空白行为4或更多时,通过删除空行将文件重新写入新日志。换句话说,我必须将任何4个连续的空白行(或更多行)压缩成一行;但是文件中的1,2或3行的任何情况都必须保留格式。我试图在线获得解决方案,但我唯一能找到的是

perl -00 -pe ''

perl -00pe0  

另外,我在vim中看到这样的示例来删除4个空行:%s/^\n\{4}//的块,这些块匹配我正在寻找的但是它在vim而不是Perl。任何人都可以帮助吗?感谢。

5 个答案:

答案 0 :(得分:8)

将4个以上连续的Unix风格的EOL折叠为一个换行符:

$ perl -0777 -pi.bak -e 's|\n{4,}|\n|g' file.txt

使用look-behind的替代风味:

$ perl -0777 -pi.bak -e 's|(?<=\n)\n{3,}||g' file.txt

答案 1 :(得分:1)

use strict;
use warnings;

my $cnt = 0;

sub flush_ws {
  $cnt = 1 if ($cnt >= 4);
  while ($cnt > 0) {print "\n"; $cnt--; }
}

while (<>) {
  if (/^$/) {
    $cnt++;
  } else {
    flush_ws();
    print $_;
  }
}
flush_ws();

答案 2 :(得分:0)

您的-0提示很好,因为您可以使用-0777-p模式覆盖整个文件。在perlrun中阅读有关这些人的更多信息。所以这个oneliner应该可以解决这个问题:

$ perl -0777 -pe 's/\n{5,}/\n\n/g'

如果连续最多有四个新行,则不会发生任何事情。五个或更多的换行符(四个空行或更多行)被两个换行符(一个空行)替换。请注意此处的/g开关不仅可以替换第一个匹配项。

解密代码:

BEGIN { $/ = undef; $\ = undef; }
LINE: while (defined($_ = <ARGV>)) {
    s/\n{5,}/\n\n/g;
}
continue {
    die "-p destination: $!\n" unless print $_;
}

HTH! :)

答案 3 :(得分:0)

使用GNU awk的一种方法,将记录分隔符设置为NUL:

awk 'BEGIN { RS="\0" } { gsub(/\n{5,}/,"\n")}1' file.txt

这假设您定义为空白排除空格

答案 4 :(得分:0)

这将满足您的需求

perl -ne 'if (/\S/) {$n = 1 if $n >= 4; print "\n" x $n, $_; $n = 0} else {$n++}' myfile