How do I insert a newline for every two lines, except when two consecutive newlines are encountered?

I am trying to insert a new line for every two lines of text, except that I want to rerun this pattern whenever a new paragraph is encountered (two consecutive new lines). (My desired output should not have three consecutive new lines.)

For example, here's my input text:

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.

      

And here is my desired output:

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.

      

I've tried using awk:

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

      

but this command does not restart the template after a new paragraph. Instead, I would get the following output from my example above:

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.

      

As this unwanted output shows, without restarting the template, I would get instances of three consecutive newlines.

+3


source to share


5 answers


Perl's paragraph mode can help:

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

      

Output



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.

      

Based on @ Borodin's comment:

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

      

+5


source


Pearl for the rescue!

perl -00 -ple '$i = 0; s/\n/($i++ % 2) ? "\n\n" : "\n"/eg'

      



  • -00

    turns on paragraph mode, that is, Perl reads input in blocks separated by at least two newlines.
  • -l

    removes two newlines from the end of each block after reading it, but returns them before printing, avoiding three consecutive newlines.
  • /e

    evaluates the right side of the substitution as code.
  • $i++ % 2

    is the increment plus modulus. It returns 1 for rows 1, 3, 5, etc. In every block.
  • condition ? then : else

    is a ternary operator. New lines on lines 1, 3, 5 ... will be replaced with two new lines, the rest will remain.
  • $i

    - reset so that each block starts at 0 again.
+3


source


This will also restart the template for each paragraph:

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.

      

Output

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.

      

+2


source


This might work for you (GNU sed):

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

      

Remove all blank lines in front of the non-blank line, print it, if the next line is blank, you can add a new line (if it is not the last line) and repeat.

If you prefer an empty string to indicate the last true verse:

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

      

As an afterthought to group consecutive lines sequentially:

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

      

This will divide the texts into groups of no more than five lines.

+1


source


If you wait if the next line is empty to decide to insert a new line, it becomes relatively easy. Here expressed in 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

      

Run it like this:

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

      

Or, for example, like this:

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

      

Below is the output of the second call, followed by the header added to the script (the header is specific to GNU awk):

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

      

Output:

===>>>   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.

      

Golf version:

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

      

0


source







All Articles