用一个换行符替换两个换行符,用两个换行符替换两个以上的换行符
Replace two newlines with a single one and more than two with two newlines
我有一个如下所示的文件:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
我怎样才能让它看起来像这样:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
即用一个换行符替换两个连续的换行符,用两个换行符替换两个以上的换行符?
好吧,我自己想通了:
perl -0777 -i -pe 's/\n\n/\n/g' file
如果我们查看换行序列,这就是我们想要的:
\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
代表“空白”,包含一行中遇到的空白行数。
参见 。
在 Perl 中:要使用正则表达式匹配连续的换行符,您不能在 line-by-line 模式下阅读。这就是我们将文件压缩成一个字符串的原因。
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+
或者如果您喜欢 one-liner:
perl -0777 -pe's/\n\n?\K\n+//g' file
添加 -i
选项以 in-place 在您满意更改按预期工作时编辑文件。 -i.bak
保存备份。
使用awk
的解决方案:
awk 'BEGIN {minus2 = "a"; minus1 = "a";}{if([=10=]==""){if(minus1=="" && minus2!=""){print [=10=]}}else{print [=10=]}; minus2 = minus1; minus1 = [=10=]}' yourfile.txt
说明:要决定是否打印当前行,我需要知道前两行的内容——我将其保留为 minus2
和 minus1
。在 BEGIN
中我设置了它们(可以使用任何值,即 !=""
)。以上可能会在 pseudo-code 中显示如下 对于每一行 do:
if line is empty:
if previous line is empty and previous previous non-empty:
print line
else:
do nothing
else:
print line
然后我更新 minus1
和 minus2
以便下一行具有正确的值。
简单地说,我只打印了每组空行中的第二个空行。
我有一个如下所示的文件:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
我怎样才能让它看起来像这样:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
即用一个换行符替换两个连续的换行符,用两个换行符替换两个以上的换行符?
好吧,我自己想通了:
perl -0777 -i -pe 's/\n\n/\n/g' file
如果我们查看换行序列,这就是我们想要的:
\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
代表“空白”,包含一行中遇到的空白行数。
参见
在 Perl 中:要使用正则表达式匹配连续的换行符,您不能在 line-by-line 模式下阅读。这就是我们将文件压缩成一个字符串的原因。
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+
或者如果您喜欢 one-liner:
perl -0777 -pe's/\n\n?\K\n+//g' file
添加 -i
选项以 in-place 在您满意更改按预期工作时编辑文件。 -i.bak
保存备份。
使用awk
的解决方案:
awk 'BEGIN {minus2 = "a"; minus1 = "a";}{if([=10=]==""){if(minus1=="" && minus2!=""){print [=10=]}}else{print [=10=]}; minus2 = minus1; minus1 = [=10=]}' yourfile.txt
说明:要决定是否打印当前行,我需要知道前两行的内容——我将其保留为 minus2
和 minus1
。在 BEGIN
中我设置了它们(可以使用任何值,即 !=""
)。以上可能会在 pseudo-code 中显示如下 对于每一行 do:
if line is empty:
if previous line is empty and previous previous non-empty:
print line
else:
do nothing
else:
print line
然后我更新 minus1
和 minus2
以便下一行具有正确的值。
简单地说,我只打印了每组空行中的第二个空行。