0

Say I have a simple file with tab separated values:

a b c d e f
aa bb cc dd ee ff
A B C D E F

How can I transpose it like a matrix: tabs become newlines and the opposite, to become such:

a aa A
b bb B
c cc C
d dd D
e ee E
f ff F

The lines can be fairly long. I know how to do it in C by reading everything into a 2D buffer and then writing the whole thing out, but I was looking for a simpler solution using shell scripts but couldn't think of anything obvious.

dargaud
  • 2,431
  • 2
  • 26
  • 39

2 Answers2

1

Unless you proceed with multiple passes (as many passes as there are elements in a line), I don't see how you can avoid using a buffer of some kind.

What kind of shell are you referring to, by the way?

This other SO post (An efficient way to transpose a file in Bash) seems to address exactly that in bash.

Community
  • 1
  • 1
Tonio
  • 414
  • 5
  • 17
  • Thanks, I'd seen several posts with similar questions but different constrains, but I'd missed this one. – dargaud Jul 08 '14 at 08:38
0

Yes, you can do it in a very simply way:

#!/bin/bash

ar1=( a b c d e f )
ar2=(aa bb cc dd ee ff )
ar3=(A B C D E F )

for ((i=0; i<${#ar1[@]}; i++)); do

    printf " %s  %s  %s\n" ${ar1[i]} ${ar2[i]} ${ar3[i]}

done

output:

a  aa  A
b  bb  B
c  cc  C
d  dd  D
e  ee  E
f  ff  F

Modifying to read the arrays from the command line is straight forward as well:

ar1=( $1 )
ar2=( $2 )
ar3=( $3 )

for ((i=0; i<${#ar1[@]}; i++)); do

    printf "  %2s  %2s  %2s\n" ${ar1[i]} ${ar2[i]} ${ar3[i]}

done

The command line and output:

$ ./mtrxpose.sh "a b c d e f" "aa bb cc dd ee ff" "A B C D E F"
a  aa   A
b  bb   B
c  cc   C
d  dd   D
e  ee   E
f  ff   F
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • I'm moderately proficient in bash, but I've never used arrays. How do you read a line into an array ? Or several lines into a 2D array ? – dargaud Jul 08 '14 at 08:37
  • really easy, you can read them in as double quoted arguments eg. `"a b c d e f"` `"aa bb cc dd ee ff"`, etc.. into the arrays `ar1=( $1 )` `ar2=( $2 )` and so on. That will give you 3 arrays of 6 elements each. The loop simply writes out all of the 1st row of each, then the 2nd row, ... – David C. Rankin Jul 08 '14 at 08:45