35

I have simple text file named "example".

Reading with terminal command: cat example

Output:

abc cdef ghi jk lmnopq rst uv wxyz

I want to convert (transform) into following form: (expected output from cat example)

abc
cdef
ghi
jk
lmnopq
rst
uv
wxyz

How can I do this via the command-line?

(This is only an example file, I want to convert word's position in vertical-column)

Pandya
  • 34,843
  • 42
  • 126
  • 186

6 Answers6

71

A few choices:

  1. The classic, use tr:

    tr ' ' '\n' < example
    
  2. Use cut

    cut -d ' ' --output-delimiter=$'\n' -f 1- example
    
  3. Use sed

    sed 's/ /\n/g' example
    
  4. Use perl

    perl -pe 's/ /\n/g' example
    
  5. Use the shell

    foo=$(cat example); echo -e ${foo// /\\n}
    
terdon
  • 98,183
  • 15
  • 197
  • 293
  • 1
    For the `sed` example I needed to add a `$` to get bash to replace with an actual newline ie: `sed $'s/ /\\\n/g' example` – acumartini Sep 09 '19 at 20:38
  • 1
    Above example for OSX sed, for gnu-sed: `sed $'s/ /\\n/g'` – acumartini Sep 09 '19 at 20:44
  • 1
    @acumartini GNU `sed` (which is the default on Ubuntu, the others aren't relevant on this site) can deal with `\n` without requiring [ANSI-C quotes](https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html). So on a GNU system, `sed 's/ /\n/g' example` works fine and there is no need for `sed $'s/ /\\n/g'`. You needed to add the `$` because macOS uses BSD sed, but that isn't on topic here. – terdon Feb 24 '21 at 10:51
  • the lowest denomitator (from sh) is to represent the new line char as `$'\n'` - like in the example for `cut` - applicable to all the rest of the examples as well – Radagast the Brown Dec 11 '22 at 12:47
  • @RadagasttheBrown not sure what you mean. The `$'\n'` syntax is the more limited approach since it is the only one that requires a shell that understands `$'\n'` (for example, `dash` doesn't work well with it). The rest all use robust, portable solutions. So you would never use `$'\n'` in the other commands since that would only make them slightly less universal. – terdon Dec 12 '22 at 11:55
  • @terdon - realy?? interestring!!! I write for the bare minimum - plain `sh`, and learnt to use `$'\n'` as the most common denominator. I never thought that `dash` won't understand it... omg. what a gotcha that is for me!! – Radagast the Brown Dec 13 '22 at 15:54
  • @terdon - OMG. I just found I was testing against `busybox` sh, which is more sophisticated than plain POSIX.... ... tsk tsk tsk... thanks for the eye opener. anyway - according to https://serverfault.com/questions/241959/whats-the-busybox-default-shell - it seems to be ash / older dash - so `$'\n'` works in dash... – Radagast the Brown Dec 15 '22 at 10:54
16

Try the below command

awk -v RS=" " '{print}' file

OR

awk -v RS='[\n ]' '{print}' file

Example:

$ awk -v RS=" " '{print}' example
abc
cdef
ghi
jk
lmnopq
rst
uv
wxyz

Explanation:

RS (Record separator) is an built-in awk variable. In the first command, the value given to the Record separator variable is space. Awk breaks the line from printing whenever it finds a space.

In the second command, the value given to the RS variable is space or a new line character.This command eliminates the extra blank line appeared while running the first command.

Mike Slinn
  • 215
  • 2
  • 13
Avinash Raj
  • 77,204
  • 56
  • 214
  • 254
10

You can use xargs,

cat example | xargs -n 1

or, better

xargs -n 1 < example
sourav c.
  • 44,037
  • 20
  • 101
  • 128
3

Using a perl oneliner:

perl -p -i -e 's/\s/\n/g' example

It will replace spaces and tabs with "ENTER" (aka \n)

Sylvain Pineau
  • 61,564
  • 18
  • 149
  • 183
2

No one posted python, so here's that:

python -c "import sys;lines=['\n'.join(l.strip().split()) for l in sys.stdin.readlines()];print('\n'.join(lines))" < input.txt 

We redirect input file into python's stdin stream, and read it line by line. Each line is stripped of its trailing newline, split into words, and then rejoined into one string where each word is separated by newline.This is done to ensure having one word per line and avoid multiple newlines being inserted in case there's multiple spaces next to each other. Eventually we end up with list of strings, which is then again joined into larger string, and printed out to stdout stream. That later can be redirected to another file with > out.txt redirection.

Sergiy Kolodyazhnyy
  • 103,293
  • 19
  • 273
  • 492
1

Similar to the 'tr' above but with the additions:

  • Also works for tabs

  • Converts multiple spaces or tabs to 1 newline

    tr -s '[:space:]' '\n' < example
    
AstroTom
  • 111
  • 2