我正在编写一个Perl脚本来读取日志,以便在看到任何连续的空白行为4或更多时,通过删除空行将文件重新写入新日志。换句话说,我必须将任何4个连续的空白行(或更多行)压缩成一行;但是文件中的1,2或3行的任何情况都必须保留格式。我试图在线获得解决方案,但我唯一能找到的是
perl -00 -pe ''
或
perl -00pe0
另外,我在vim中看到这样的示例来删除4个空行:%s/^\n\{4}//
的块,这些块匹配我正在寻找的但是它在vim而不是Perl。任何人都可以帮助吗?感谢。
答案 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