15

Suppose I have a file:

File1:

PAPER  TEAM  MANISH NISHA GARIMA JYOUTI ........etc 

File2 I want:

PAPER    
TEAM
MANISH
NISHA
GARIMA    
JYOUTI

Rows to column conversion of File1.

12 Answers 12

20

Using tr, replace each repeated space character() with a single new-line(\n) character.

tr -s ' '  '\n'< infile > outfile

But I think you want something like this?

1 2 3 4         1 a #
a b c d   -->   2 b $
# $ @ %         3 c @
                4 d %

With awk we could do:

awk '{ for (i=1; i<=NF; i++) RtoC[i]= (RtoC[i]? RtoC[i] FS $i: $i) } 
    END{ for (i in RtoC) print RtoC[i] }' infile

This joins each same filed number positon into together and in END prints the result that would be first row in first column , second row in second column, etc. Of course the input file is limited to your memory size.

  • I tried with same data and code, it printed last column as first record like 4 d % and then 2nd record 1 a # and so on. – Abhinay Jan 25 at 5:16
8

You could simply do this through grep. By default grep, would print the match in a separate newline .

grep -oP '\S+' infile > outfile

OR

grep -o '[^[:space:]]\+' infile > outfile
  • 1
    +1 for creative use of grep – Volker Siegel May 21 '16 at 0:25
8

You could also use the fmt command:

~$ cat f
PAPER  TEAM  MANISH NISHA GARIMA JYOUTI
~$ fmt -1 f
PAPER
TEAM
MANISH
NISHA
GARIMA
JYOUTI
7

With GNU datamash:

$ datamash -W transpose <file
PAPER
TEAM
MANISH
NISHA
GARIMA
JYOUTI
  • datamash seems like the best tool for the task, but fascinating how many other tools could be used! – Mark Stewart Sep 19 '18 at 20:07
6

You can also do this using sed:

$ sed -e 's/  */\n/g' file1 > file2

NOTE: Doesn't handle the situation where the words contain spaces.

5

Using awk, setting the output field separator (OFS) as the record (line) separator (RS):

awk '{OFS=RS;$1=$1}1' file > file2
2

Using a for loop:

for val in `cat file1` ; do echo $val >> file2; done;
0

You can also try using sed

$ sed -i.bak s@' '@'\n'@g infile.txt

Please note that I am using @ as a separator for the substitution operation. This will also create a backup file. In case you don't need a backup remove .bak

$ sed -i s@' '@'\n'@g infile.txt
0

Python version:

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

This uses < redirection into python's stdin from input.txt and writes to output.txt using > redirection. The one-liner itself reads in all lines from stdin into a list of strings,where all spaces are replaced with newlines, and we rebuild whole text using .join() function.

Alternative approach to avoid multiple spaces in series being replaced with newlines is to use .split() to break line into list of words. That way , we can ensure that each word is separated only by one newline

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

Using xargs, (stolen from souravc's answer):

xargs -n 1 < File1 > File2

Or if any minor reformatting is needed, use printf format strings as however might be needed:

xargs printf '%s\n' < File1 > File2
0

My solution would be:

#!/bin/bash
cols=$(head -1 file.txt | wc -w)
for i in $(seq 1 $cols); do
cut -d ' ' -f$i file.txt | tr '\n' ' ' | sed s'/.$//'
echo
done
-1
awk '{for (i=1;i<=NF;i++) {print($i)}}' file > File2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.