4

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

perl -00 -pe ''

或者

perl -00pe0  

此外,我在 vim 中看到这样的示例删除:%s/^\n\{4}//与我正在寻找的内容匹配的 4 个空行块,但它是在 vim 而不是 Perl 中。有人可以帮忙吗?谢谢。

4

5 回答 5

8

要将 4+ 个连续的 Unix 样式 EOL 折叠到一个换行符:

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

使用后视的另一种风味:

$ perl -0777 -pi.bak -e 's|(?<=\n)\n{3,}||g' file.txt
于 2012-09-06T11:56:09.967 回答
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();
于 2012-09-06T10:08:26.603 回答
0

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

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

这假设您定义的空不包括空格

于 2012-09-06T12:45:58.930 回答
0

这将做你需要的

perl -ne 'if (/\S/) {$n = 1 if $n >= 4; print "\n" x $n, $_; $n = 0} else {$n++}' myfile
于 2012-09-06T13:41:27.410 回答
0

您的-0提示是一个很好的提示,因为您可以使用-0777slurp 模式下的整个文件-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 $_;
}

!:)

于 2012-09-06T12:20:18.447 回答