How can I format the output of a bash command in neat columns


Bash Problem Overview

I have a function which outputs many rows of information which I want to format in columns. The problem is that the width of any particular "cell" (if I may use that term) of data is variable, so piping it to something like awk does not give me what I want.

The function is "keys" (not that it matters) and I'm trying something like this:

$ keys | awk '{ print $1"\t\t" $2 }'

but the output (a snippet of it, that is) looks like this:

"option-y"		yank-pop
"option-z"		execute-last-named-cmd
"option-|"		vi-goto-column
"option-~"		_bash_complete-word
"option-control-?"		backward-kill-word
"control-_"		undo
"control-?"		backward-delete-char

How can I force things to stay in neat columns? Is this possible with awk, or do I need to use something else?

Bash Solutions

Solution 1 - Bash">`column(1)`</a> is your friend.

$ column -t <<< '"option-y"      yank-pop
> "option-z"      execute-last-named-cmd
> "option-|"      vi-goto-column
> "option-~"      _bash_complete-word
> "option-control-?"      backward-kill-word
> "control-_"     undo
> "control-?"     backward-delete-char
> '
"option-y"          yank-pop
"option-z"          execute-last-named-cmd
"option-|"          vi-goto-column
"option-~"          _bash_complete-word
"option-control-?"  backward-kill-word
"control-_"         undo
"control-?"         backward-delete-char

Solution 2 - Bash

Found this by searching for "linux output formatted columns".

For your needs, it's like:

awk '{ printf "%-20s %-40s\n", $1, $2}'

Solution 3 - Bash

While awk's printf can be used, you may want to look into pr or (on BSDish systems) rs for formatting.

Solution 4 - Bash

Since AIX doesn't have a "column" command, I created the simplistic script below. It would be even shorter without the doc & input edits... :)

# convert STDIN to multiple columns on STDOUT
#       Usage: column-width number-of-columns  file...
$width = shift;
($width ne '') or die "must give column-width and number-of-columns\n";
$columns = shift;
($columns ne '') or die "must give number-of-columns\n";
($x = $width) =~ s/[^0-9]//g;
($x eq $width) or die "invalid column-width: $width\n";
($x = $columns) =~ s/[^0-9]//g;
($x eq $columns) or die "invalid number-of-columns: $columns\n";

$w = $width * -1; $c = $columns;
while (<>) {
        if ( $c-- > 1 ) {
                printf "%${w}s", $_;
        $c = $columns;
        printf "%${w}s\n", $_;
print "\n";

Solution 5 - Bash


xargs -n2  printf "%-20s%s\n"

or even

xargs printf "%-20s%s\n"

if input is not very large.

Solution 6 - Bash

If your output is delimited by tabs a quick solution would be to use the tabs command to adjust the size of your tabs.

tabs 20
keys | awk '{ print $1"\t\t" $2 }'


All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioniconoclastView Question on Stackoverflow
Solution 1 - BashIgnacio Vazquez-AbramsView Answer on Stackoverflow
Solution 2 - BashKoterpillarView Answer on Stackoverflow
Solution 3 - BashgeekosaurView Answer on Stackoverflow
Solution 4 - Bashuser2961066View Answer on Stackoverflow
Solution 5 - BashVytenis BivainisView Answer on Stackoverflow
Solution 6 - BashLewis RView Answer on Stackoverflow