我有一个看起来像这样的文件:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
如何使它看起来像这样:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
即用一个换行符替换两个连续的换行符,用两个换行符替换两个以上的换行符?
答案 0 :(得分:3)
如果我们查看换行的顺序,这就是我们想要的:
\n -> \n (No change)
\n\n -> \n
\n\n\n+ -> \n\n
简单的解决方案涉及将整个文件加载到内存中。
perl -0777pe's/\n\n?\K\n+//g'
如果要避免这种情况,可以使用以下内容:
perl -ne'
chomp;
$b = length ? 0 : $b+1;
CORE::say if $b==0 || $b==2;
'
$b
代表“空白”,包含一行中遇到的空白行数。
答案 1 :(得分:2)
在Perl中:要使用正则表达式匹配连续的换行符,则不能以逐行模式阅读。这就是为什么我们将文件插入单个字符串的原因。
my $str = do { local $/; <DATA> }; # slurp the file into a single string
$str =~ s/\n\n?\K\n+//g;
print $str;
替换正则表达式与单个换行符\n
相匹配,后跟一个可选的换行符\n?
,并保留\K
,后跟1个或多个换行符\n+
,删除。由于所有的量词都是贪婪的,因此当存在3个或更多行时,?
将保留两个换行符的大小写。
Case \n\n?\K\n+ explanation result
\n 1 x x no match, no substitution no change
\n\n 1 0 1 match, skip, match 1 time \n remove \n
\n\n\n+ 1 1 1+ match, match, match 1+ times \n\n remove \n+
或者,如果您希望将其作为单线使用:
perl -0777 -pe's/\n\n?\K\n+//g' file
添加-i
选项可在您满意更改按预期进行时就地编辑文件。 -i.bak
保存备份。
答案 2 :(得分:0)
好吧,我自己弄清楚了:
perl -0777 -i -pe 's/\n\n/\n/g' file
答案 3 :(得分:0)
使用awk
的解决方案:
awk 'BEGIN {minus2 = "a"; minus1 = "a";}{if($0==""){if(minus1=="" && minus2!=""){print $0}}else{print $0}; minus2 = minus1; minus1 = $0}' yourfile.txt
说明:要确定是否打印当前行,我需要知道前两行的内容-我将其保留为minus2
和minus1
。在BEGIN
中设置它们(可以使用任何值,!=""
)。上面的内容可能以伪代码的形式出现,如下所示,每行都用 :
if line is empty:
if previous line is empty and previous previous non-empty:
print line
else:
do nothing
else:
print line
然后我更新minus1
和minus2
,以便在下一行具有正确的值。
简而言之,我确实从每组空行中仅打印了第二个空行。