4

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?

0

4 Answers 4

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
  • Instead of awk, csplit might be more suitable as it is designed for file splitting on a pattern match. In this case match empty lines and delete the match pattern: csplit -f file_ --suppress-matched infile.txt '/^$/' '{*}' . ALSO: Note that the pasting via paste file* might be problematic when having file1 and file10. Commented Sep 18, 2020 at 8:17
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

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
1
  • This is truncate the List B, List C columns if List A is lesser then B and C Commented Nov 14, 2022 at 12:00
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      

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.