36

How can I use text-processing tools to insert a new line after every N lines?

Example for N=2:

INPUT:

sadf asdf yxcv cxv eqrt asdf 

OUTPUT:

sadf asdf yxcv cxv eqrt asdf 

6 Answers 6

51

With awk:

awk ' {print;} NR % 2 == 0 { print ""; }' inputfile 

With sed (GNU extension):

sed '0~2 a\\' inputfile 

With bash:

#!/bin/bash lines=0 while IFS= read -r line do printf '%s\n' "${line}" ((lines++ % 2)) && echo done < "$1" 
2
  • 2
    Arithmetic evaluation can be used directly as condition, no need for the [[ ]] to test: while read line; do echo "$line"; ((lines++ % 2)) && echo; done. Commented Oct 29, 2011 at 14:57
  • 2
    Be aware that the above documented command sed '0~2 a\ ' adds a space to each inserted newline. If you wanted to add a newline after each line, any of these similarly work: sed '0~1 a\ ', sed 'a\ ', or just sed G. Commented Nov 7, 2013 at 19:20
9

sed (GNU)

With (GNU) sed:

sed '0~2G' 

Short (ugly for N=100):

sed 'n;G' 

man sed explains ~ as:

first ~ step
Match every step'th line starting with line first. For example, ``sed -n 1~2p'' will print all the odd-numbered lines in the input stream, and the address 2~5 will match every fifth line, starting with the second. first can be zero; in this case, sed operates as if it were equal to step. (This is an extension.)

sed (other)

With other sed (Count new lines):

sed -e 'p;s/.*//;H;x;/\n\{2\}/{g;p};x;d' 

Or, to be more portable, written as (remove comments for some versions of sed) :

sed -e ' # Start a sed script. p # Whatever happens later, print the line. s/.*// # Clean the pattern space. H # Add **one** newline to hold space. x # Get the hold space to examine it, now is empty. /\n\{2\}/{ # Test if there are 2 new lines counted. g # Erase the newline count. p # Print an additional new line. } # End the test. x # match the `x` done above. d # don't print anything else. Re-start. ' # End sed script. 

awk

With awk, probably:

awk '1 ; NR%2==0 {printf"\n"} ' 
6

Using paste

 paste -d'\n' - - /dev/null <file 
5
sed n\;G <infile 

... is all you need ...

For example:

seq 6 | sed n\;G 

OUTPUT:

1 2 3 4 5 6 

...(and a blank follows the 6 as well)...or...

seq 5 | sed n\;G 

OUTPUT:

1 2 3 4 5 

(and no blank follows the 5)

If a blank should always be omitted in a last line case:

sed 'n;$!G' <infile 
3

Another awk flavour:

awk '{ l=$0; getline; printf("%s\n%s\n\n", l, $0) }' 
1
  • 1
    "This answer was flagged as low-quality because of its length and content." I'll accept it... ;-) Commented Jan 27, 2015 at 10:31
0

Using Perl

~$ perl -ne 'print $_; if ($. % 2 == 0) { print "\n"};' file 

Using Raku (formerly known as Perl_6)

~$ raku -ne '.put; if (++$ %% 2) { print "\n"};' file 

The Perl answer uses $_ which is Perl's topic variable, and $. which is Perl's line-number variable. If the line number % modulo 2 equals zero, insert a \n newline.

The Raku answer uses $_ but in an abbreviated form: .put is short for $_.put. The Raku answer uses ++$ an anonymous pre-incrementing counter variable. Raku's %% 'Divisibility operator' is set to return True if ++$ % 2 == 0, so again (like the Perl answer), a \n newline is inserted.

Sample Input:

sadf asdf yxcv cxv eqrt asdf 

Sample Output:

sadf asdf yxcv cxv eqrt asdf 

Perl References:
https://perldoc.perl.org
https://www.perl.org

Raku References:
https://docs.raku.org
https://raku.org

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.