NickSerao
NickSerao

Reputation: 43

Split one column by every into "n" columns with one character each

I have a file with one single column and 10 rows. Every column has the same number of characters (5). From this file I would like to get a file with 10 rows and 5 columns, where each column has 1 character only. I have no idea on how to do that in linux.. Any help? Would AWK do this?

The real data has many more rows (>4K) and characters (>500K) though. Here is a short version of the real data:

31313
30442
11020
12324
00140
34223
34221
43124
12211
04312

Desired output:

3 1 3 1 3
3 0 4 4 2
1 1 0 2 0
1 2 3 2 4
0 0 1 4 0
3 4 2 2 3
3 4 2 2 1
4 3 1 2 4
1 2 2 1 1
0 4 3 1 2

Thanks!

Upvotes: 2

Views: 446

Answers (4)

Tom Fenech
Tom Fenech

Reputation: 74655

I think that this does what you want:

$ awk -F '' '{ $1 = $1 }1' file
3 1 3 1 3
3 0 4 4 2
1 1 0 2 0
1 2 3 2 4
0 0 1 4 0
3 4 2 2 3
3 4 2 2 1
4 3 1 2 4
1 2 2 1 1
0 4 3 1 2

The input field separator is set to the empty string, so every character is treated as a field. $1 = $1 means that awk "touches" every record, causing it to be reformatted, inserting the output field separator (a space) between every character. 1 is the shortest "true" condition, causing awk to print every record.

Note that the behaviour of setting the field separator to an empty string isn't well-defined, so may not work on your version of awk. You may find that setting the field separator differently e.g. by using -v FS= works for you.

Alternatively, you can do more or less the same thing in Perl:

perl -F -lanE 'say "@F"' file

-a splits each input record into the special array @F. -F followed by nothing sets the input field separator to the empty string. The quotes around @F mean that the list separator (a space by default) is inserted between each element.

Upvotes: 4

karakfa
karakfa

Reputation: 67507

another unix toolchain for this task

$ while read line; do echo $line | fold -w1 | xargs; done < file

3 1 3 1 3
3 0 4 4 2
1 1 0 2 0
1 2 3 2 4
0 0 1 4 0
3 4 2 2 3
3 4 2 2 1
4 3 1 2 4
1 2 2 1 1
0 4 3 1 2

Upvotes: 0

anubhava
anubhava

Reputation: 785286

You can use this sed as well:

sed 's/./& /g; s/ $//' file

3 1 3 1 3
3 0 4 4 2
1 1 0 2 0
1 2 3 2 4
0 0 1 4 0
3 4 2 2 3
3 4 2 2 1
4 3 1 2 4
1 2 2 1 1
0 4 3 1 2

Upvotes: 2

chepner
chepner

Reputation: 531420

Oddly enough, this isn't trivial to do with most standard Unix tools (update: except, apparently, with awk). I would use Python:

python -c 'import sys; map(sys.stdout.write, map(" ".join, sys.stdin))' in.txt > new.txt

(This isn't the greatest idiomatic Python, but it suffices for a simple one-liner.)

Upvotes: 0

Related Questions