VNA
VNA

Reputation: 625

Transpose till "n"th column into row:

I would like to transpose column to row by every 3rd column.

Input.txt

Name
Age
Place
aa
22
xx
bb
33
yy
cc
44
zz
....
....

Desired Output

Name,Age,Place
aa,22,xx
bb,33,yy
cc,44,zz

I have tried below command and in-complete

awk '
{
  for(c = 1; c <= NR; c++)    { a[c]=$c }
}
END {
  for(r = 1; r <= NR; r++) {
    for(t = 1; t <= 3; t++) {
      printf("%s ", a[c])
    }
    print ","
  }
}'  Input.txt

Looking for your suggestions...

Upvotes: 0

Views: 622

Answers (1)

fedorqui
fedorqui

Reputation: 289835

There are many good tools for this.

This awk!

$ awk 'ORS=NR%3?",":RS' file
Name,Age,Place
aa,22,xx
bb,33,yy
cc,44,zz

It sets the output field separator as , whenever the line is not multiple of 3. This way, it joins every group of 3 lines.

More info in Idiomatic awk.

xargs

$ xargs -n3 <file
Name Age Place
aa 22 xx
bb 33 yy
cc 44 zz

This gets the input in blocks of X items, defined by -n X. Then you can replace spaces with commas with tr or sed.

paste

$ paste -d"," - - - <file
Name,Age,Place
aa,22,xx
bb,33,yy
cc,44,zz

This joins every 3 input and uses delimiter , as separator.


Regarding transpose itself, I wrote a snippet a while ago in Using bash to sort data horizontally:

transpose () {
  awk '{for (i=1; i<=NF; i++) a[i,NR]=$i; max=(max<NF?NF:max)}
        END {for (i=1; i<=max; i++)
              {for (j=1; j<=NR; j++) 
                  printf "%s%s", a[i,j], (j<NR?OFS:ORS)
              }
        }'
}

Upvotes: 3

Related Questions