0

I have a file as such, infile.txt:

foo bar
hello world
blah blah black sheep

I want to get:

foo
bar

hello
wolrd

blah 
blah 
black 
sheep

I've tried this

echo infile.txt | sed -e 's/[[:space:]]/\n/g' | grep -v '^$'

but it doesn't recognize the line breaks and outputs:

foo
bar
hello
wolrd
blah 
blah 
black 
sheep

How do I achieve the desired output?

alvas
  • 115,346
  • 109
  • 446
  • 738

4 Answers4

3

A sed version: (does not give new line at end)

sed '$!G;s/ /\n/g' file
foo
bar

hello
world

blah
blah
black
sheep

The G adds new line to the pattern space, and copies the hold space after the new line.
But since hold space is empty, it only adds new line. The $! prevents it run on last line.
s/ /\n/g replace all space with new line.


Another sed version: (does not give new line at end)
(Based on NeronLeVelu post)

sed '$!s/$/\n/g;s/ /\n/g' file
foo
bar

hello
world

blah
blah
black
sheep

How it works:
$! not do this on last line -> s/$/\n/g replace end of line $ with \n so you get two new line.
s/ /\n/g replace all space with newline.

Jotne
  • 40,548
  • 12
  • 51
  • 55
2

Here is an awk

awk -v OFS="\n" -v ORS="\n\n" '{$1=$1}1' file
foo
bar

hello
world

blah
blah
black
sheep

You may also use:

awk '$1=$1' OFS="\n" ORS="\n\n" file

But this is more robust

awk '{$1=$1}1' OFS="\n" ORS="\n\n" file

Another version:

awk '{gsub(/($| )/,"\n")}1' file

PS, all awk above adds a newline at the end.

This does not add new line at the end if that is a problem:

awk 'NR>1 {print a"\n"} {gsub(/ /,"\n");a=$0} END {print a}' file
foo
bar

hello
world

blah
blah
black
sheep
Jotne
  • 40,548
  • 12
  • 51
  • 55
  • +1. It could also be done with `awk '{gsub(/( |$)/,RS)}1' file` or `sed -r 's/( |$)/\n/g' file` but IMHO `awk -v OFS="\n" -v ORS="\n\n" '{$1=$1}1' file` is the right way to do it clearly and explicitly implements exactly what's required (i.e. change the space field separator to a newline and change the newline output record separator to 2 newlines) and it's easily extended. – Ed Morton Aug 26 '14 at 17:10
  • 1
    @EdMorton Updated my post. PS the `sed` give one blank line at end, so it may be written: `sed '$!s/$/\n/g;s/ /\n/g'` – Jotne Aug 26 '14 at 17:30
  • The awk one will give a blank line at the end too but I figure that's fine since every other group of lines in the file is succeeded by a blank line too. – Ed Morton Aug 26 '14 at 18:45
0

You could use the below sed command,

$ sed ':a;N;$!ba;s/\n/\n\n/g;s/ /\n/g' file
foo
bar

hello
world

blah
blah
black
sheep
  • Single new line characters are replaced by double new line characters.
  • Again spaces are replaced by a new line character.
Avinash Raj
  • 172,303
  • 28
  • 230
  • 274
0
sed '$ !s/$/\
/;s/ /\
/g' YourFile
  1. add a new line at the end of each line but last
  2. replace space by new line
NeronLeVelu
  • 9,908
  • 1
  • 23
  • 43