3

I have a file containing lists on Solaris:

List A
hi
hello
hw r u

List B
Hi
Yes

List C
Hello

I need to transpose the lists as shown below:

List A    List B    List C
hi        Hi        Hello
hello     Yes
hw r u

How can I do this on Solaris?

-1

GNU awk approach:

awk 'BEGIN{ max=0 }
     /^List/{ if(k && k>max) { max=k; idx=c } ++c; k=0 }
     NF{ a[c][++k]=$0 }
     END{ 
         for(i=1;i<=max;i++) 
             for(j=1;j<=c;j++) printf "%s%s",a[j][i],(j==c)?ORS:"\t" 
     }' file | column -ts$'\t'

The output:

List A  List B  List C
hi      Hi      Hello
hello   Yes
hw r u
3

You could use awk to split each block into separate files, then paste them together (below is assuming always there is empty lines between each lists).

awk '/^$/ {N++;next}{print >"file"N}' infile.txt
paste file*

Also you can move the paste command into awk.

awk '/^$/ {N++;next}{print >"file"N} END{system("paste file*")}' inile.txt

The output is:

List A    List B    List C
hi        Hi        Hello
hello     Yes
hw r u

to having beauty indentation in result when varying lines length like below:

Input file:

list A
hi
hello
hw r u

List B
Hi this is list B
Yes

List C
Hello, this is list C

you can do paste file* |column -s $'\t' -tn and will have result:

list A  List B             List C
hi      Hi this is list B  Hello, this is list C
hello   Yes
hw r u
1

Besides of my previous answer, there is also csplit command to split the file in that same way and then use paste command to get desired output.

csplit -zs -f outputfile inputfile '/^List/' '{*}'
paste outfile*
  • '/^List/' is a pattern to match and break the file there into the next new file
  • '{*}' repeat the pattern as many times as possible
  • -z is used to remove empty output files; and -s is used to do not print counts of output file sizes
  • -f is used to define custom prefix outputfile## where ## is by default 2 digits, you can define it with -n N (N is number of digits in suffix after defined prefix)
0

Command

for i in "List A" "List B" "List C"; do sed -n "/$i/,/^$/p" h.txt >"$i.txt"; done

paste List\ *

output

List A  List B  List C
hi  Hi  Hello
hello   Yes 
hw r u      

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.