octosquidopus
octosquidopus

Reputation: 3713

Printing text variables in columns

I am trying to print the contents of two variables in columns, side-by-side. I want the width of the columns to be 50% of the display: width=$(($(tput cols)/2)), and lines should break on spaces; not in the middle of words. Both variables have a considerable amount of text:

Variable 1:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue.

Variable 2:

Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor.

Expected result:

Lorem ipsum dolor sit amet,      Nam tincidunt congue enim,
consectetur adipiscing elit.     ut porta lorem lacinia
Donec a diam lectus. Sed sit     consectetur. Donec ut libero
amet ipsum mauris. Maecenas      sed arcu vehicula ultricies
congue ligula ac quam viverra    a non tortor. Lorem ipsum
nec consectetur ante             dolor sit amet, consectetur
hendrerit. Donec et mollis       adipiscing elit. Aenean ut
dolor. Praesent et diam eget     gravida lorem. Ut turpis
libero egestas mattis sit        felis, pulvinar a semper
amet vitae augue.                sed, adipiscing id dolor.

This is the closest I got to columns, but long lines don't stay within their column's limits:

column=`tput cols`
column=$(($column/2))
printf "sometext%${column}[ $(echo -en "\033[1;31m")FAILED$(echo -en "\033[0m") ]\r$i\n"

I also looked at column, fmt, and diff, but they work with files; not variables. Any suggestions?

Upvotes: 0

Views: 123

Answers (2)

rici
rici

Reputation: 241701

This function takes four arguments, in order:

  • width
  • gutter
  • left column text
  • right column text

The gutter is the minimum spacing between the columns. Since lines are broken at spaces, the actual gutter will probably be wider.

columnate() {
  paste <(fmt -w$1 <<<"$3") <(fmt -w$1 <<<"$4") | expand -t $(($1 + $2))
}

Example:

$ c1="Lorem ipsum dolor
sit amet, consectetur adipiscing elit.
Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas
congue ligula ac quam
viverra nec consectetur ante hendrerit. Donec et
mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue."
$ c2="Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut
libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis,
pulvinar a semper sed, adipiscing id dolor."
$ columnate 39 2 "$c1" "$c2"
Lorem ipsum dolor sit amet,              Nam tincidunt congue enim, ut porta
consectetur adipiscing elit.             lorem lacinia consectetur. Donec ut
Donec a diam lectus. Sed sit amet        libero sed arcu vehicula ultricies
ipsum mauris. Maecenas congue ligula     a non tortor. Lorem ipsum dolor
ac quam viverra nec consectetur          sit amet, consectetur adipiscing
ante hendrerit. Donec et mollis          elit. Aenean ut gravida lorem. Ut
dolor. Praesent et diam eget libero      turpis felis, pulvinar a semper sed,
egestas mattis sit amet vitae augue.     adipiscing id dolor.

fmt and expand are part of GNU coreutils. paste is a Posix standard.

Upvotes: 3

shellter
shellter

Reputation: 37268

Ugly, but fits the bill, and is a generally-in-demand 'one-liner' solution to boot :-)

paste <(echo "$fileA") <(echo "$fileB") | awk -F"\t" '{printf("%-40s\t%-40s\n", $1, $2)}'


orem ipsum dolor sit amet,                      Nam tincidunt congue enim,
consectetur adipiscing elit.                    ut porta lorem lacinia
Donec a diam lectus. Sed sit                    consectetur. Donec ut libero
amet ipsum mauris. Maecenas                     sed arcu vehicula ultricies
congue ligula ac quam viverra                   a non tortor. Lorem ipsum
nec consectetur ante                            dolor sit amet, consectetur
hendrerit. Donec et mollis                      adipiscing elit. Aenean ut
dolor. Praesent et diam eget                    gravida lorem. Ut turpis
libero egestas mattis sit                       felis, pulvinar a semper
amet vitae augue.                               sed, adipiscing id dolor.

where fileA and fileB match your Variable 1 and 2 values.

Decompose the various parts and change values in the printf(...). of the "one-liner" to see how it works.

You can pass the width value you derive from columns using awk variables, like

 awk -F"\t" -v colwidth="$colWidth" '{printf("%-"colWidth"s\t%-"colWidth"\n", ...}'` 

Going to bed for now. Others can chime in as needed. Good luck. :-)

IHTH.

Upvotes: 1

Related Questions