除了遇到两个连续的新行以外,如何为每两行插入一个新行?

时间:2017-04-05 07:25:08

标签: regex macos perl awk sed

我试图为每两行文本插入一个新行,除非我想在遇到新段落(连续两行)时重新启动此模式。 (我想要的输出不应该有三个连续的新行。)

例如,这是我的输入文字:

This is my first
line to appear in
the text.

I need the second
line to appear in
the way that follows
the pattern specified.

I am not sure if
the third line will
appear as I want it
to appear because sometimes
the new line happens where
there are two consecutive 
new lines.

这是我想要的输出:

This is my first
line to appear in

the text.

I need the second
line to appear in

the way that follows
the pattern specified.

I am not sure if
the third line will

appear as I want it
to appear because sometimes

the new line happens where
there are two consecutive

new lines.

我尝试过使用awk:

    awk -v n=2 '1; NR % n == 0 {print ""}'

但是此命令在新段落后不会重新启动模式。相反,我会从上面的示例文本中获得以下输出:

This is my first
line to appear in

the text.


I need the second

line to appear in
the way that follows

the pattern specified.


I am not sure if
the third line will

appear as I want it
to appear because sometimes

the new line happens where
there are two consecutive

new lines.

由于这个不需要的输出显示,没有重新启动模式,我会得到三个连续新行的实例。

5 个答案:

答案 0 :(得分:5)

perl中的段落模式可以提供帮助:

perl -00 -ple 's/.*\n.*\n/$&\n/g'

输出

This is my first
line to appear in

the text.

I need the second
line to appear in

the way that follows
the pattern specified.

I am not sure if
the third line will

appear as I want it
to appear because sometimes

the new line happens where
there are two consecutive 

new lines.

基于@Borodin评论:

perl -00 -ple 's/(?:.*\n){2}\K/\n/g'

答案 1 :(得分:3)

Perl救援!

perl -00 -ple '$i = 0; s/\n/($i++ % 2) ? "\n\n" : "\n"/eg'
  • -00打开"段落模式",即Perl以至少两个换行符分隔的块读取输入。
  • -l在读取后从每个块的末尾删除两个换行符,但在打印前将它们返回,避免连续三个换行符。
  • /e将替换的右侧评估为代码。
  • $i++ % 2是增量加模数。它在每个块中为第1,3,5等行返回1.
  • condition ? then : else是三元运算符。第1,3,5行的换行符将被两个换行符替换,其他换行符将保留。
  • $i重置为每个块再次从0开始。

答案 2 :(得分:2)

这也会重新启动每个段落的模式:

use strict;
use warnings;

my $str = do { local $/; <DATA> };
my $i = 0;
$str =~ s/(\n+)/
  if (length $1 > 1) {
      $i = 0;
      "\n\n";
  }
  else {
      $i++ % 2 ? "\n\n" : "\n"
  }
  /ge;
print $str;

__DATA__
This is my first
line to appear in
the text.

I need the second
line to appear in
the way that follows
the pattern specified.

I am not sure if
the third line will
appear as I want it
to appear because sometimes
the new line happens where
there are two consecutive 
new lines.

<强>输出

This is my first
line to appear in

the text.

I need the second
line to appear in

the way that follows
the pattern specified.

I am not sure if
the third line will

appear as I want it
to appear because sometimes

the new line happens where
there are two consecutive 

new lines.

答案 3 :(得分:1)

这可能适合你(GNU sed):

sed '/\S/!d;n;//!b;$!G' file

删除非空行前面的所有空行,打印它,如果下一行是空的,则删除,否则追加换行(除非它是最后一行)并重复。

如果您更喜欢空行来表示最后一个真正的对联:

sed '/\S/!d;n;//G' file

作为事后的想法,以编程方式对连续行进行分组:

sed '/\S/!d;:a;N;/\n\s*$/b;s/[^\n]*/&/5;Ta;G' file

这会将文本分成不超过五行的组。

答案 4 :(得分:0)

如果你等到你知道下一行是否为空以决定插入新行,那么这就变得相对简单了。这里用awk表示:

parse.awk

# Remember line count in the paragraph with n
NF  { n++ }
!NF { n=0 }

# Only emit new-line if n is non-zero and the previous line 
# number is divisible by m
n>=m && (n-1)%m==0 { printf "\n" }

# Print $0
1

像这样运行:

awk -v m=2 -f parse.awk file

或者,例如,像这样:

awk -f parse.awk m=2 file m=3 file

下面是第二次调用的输出,并在脚本中添加了以下标题(标题是GNU awk特定的):

BEGINFILE { 
  n = 0; 
  if(FNR != NR) 
    printf "\n\n"; print "===>>>   " FILENAME ", m=" m "   <<<==="
}

输出:

===>>>   file, m=2   <<<===
This is my first
line to appear in

the text.

I need the second
line to appear in

the way that follows
the pattern specified.

I am not sure if
the third line will

appear as I want it
to appear because sometimes

the new line happens where
there are two consecutive 

new lines.


===>>>   file, m=3   <<<===
This is my first
line to appear in
the text.

I need the second
line to appear in
the way that follows

the pattern specified.

I am not sure if
the third line will
appear as I want it

to appear because sometimes
the new line happens where
there are two consecutive 

new lines.

高尔夫版本:

{n=NF?n+1:0}(n-1)%m==0&&n>=m{printf "\n"}1