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.
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communitySuppose 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.
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?
Original | Transposed |
---|---|
0 1 2 3 |
0 a # |
With awk
we could do:
awk '{ for (i=1; i<=NF; i++) RtoC[i]= (i in RtoC?RtoC[i] OFS :"") $i; }
END{ for (i=1; i<=NF; i++) 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.
You could also use the fmt
command:
~$ cat f
PAPER TEAM MANISH NISHA GARIMA JYOUTI
~$ fmt -1 f
PAPER
TEAM
MANISH
NISHA
GARIMA
JYOUTI
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!
Sep 19, 2018 at 20:07
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
Using awk
, setting the output field separator (OFS
) as the record (line) separator (RS
):
awk '{OFS=RS;$1=$1}1' file > file2
OFS
to RS
every time a line is read, you don't need to do that as it's inefficient, doing it once is enough - awk 'BEGIN{OFS=ORS} {$1=$1}1'
. I also changed RS to ORS as it is technically the output record separator you want to use, only really matters if they're different.
May 1, 2022 at 13:02
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.
\n
as newline
Jan 14, 2020 at 15:57
awk '{for(i=1;i<=NF;i++){$i=$i"\n"}}1' file1 >file2
output
PAPER
TEAM
MANISH
NISHA
GARIMA
JYOUTI
Second method
perl -pne "s/ /\n/g" file1 >file2
output
PAPER
TEAM
MANISH
NISHA
GARIMA
JYOUTI
s/\s+/\n/g
instead.
May 7, 2022 at 23:07
Using Raku (formerly known as Perl_6)
raku -ne '.put for .words;'
Sample Input:
PAPER TEAM MANISH NISHA GARIMA JYOUTI
paper team manish nisha garima jyouti
Sample Output:
PAPER
TEAM
MANISH
NISHA
GARIMA
JYOUTI
paper
team
manish
nisha
garima
jyouti
Note, there seems to be some discussion that the OP doesn't want a single column as output, i.e. that this is actually a row/column transpose question. No matter, below is how you transpose whitespace-separated "columns" in Raku (e.g. capitalized first Row becomes capitalized first Column):
~$ raku -e '.put for [Z] lines.map(*.words);' file
PAPER paper
TEAM team
MANISH manish
NISHA nisha
GARIMA garima
JYOUTI jyouti
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
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
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
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