Mark Howard
Mark Howard

Reputation: 85

Shell, column -t, treat everything after Nth space as a last column

I want to print a two column table. In the first column are paths (without spaces), in the second column are names (with spaces). I'd like to make the column treat everything after Nth space (N = 2) as belonging to a single column.

I don't need to use the column, but I'd like something short. Note: I'm not looking for other solution that expects that there are only two columns.

mark@localhost ~/.config/chromium/Default/Extensions
% for f in */*/manifest.json; do
    echo -n "$f ";
    cat $f | jq -r '.name + " " + .version';
done | column -t
cjpalhdlnbpafiamejdnhcphjbkeiagm/1.14.22_0/manifest.json     uBlock                  Origin      1.14.22          
dbepggeogbaibhgnhhndojpepiihcmeb/1.62.4_0/manifest.json      Vimium                  1.62.4                       
dffhipnliikkblkhpjapbecpmoilcama/0.3_0/manifest.json         Swap                    My          Cookies  0.3     
gcbommkclmclpchllfjekcdonpmejbdp/2017.12.6_0/manifest.json   __MSG_about_ext_name__  2017.12.6                    
gdbofhhdmcladcmmfjolgndfkpobecpg/4.19_0/manifest.json        Don't                   track       me       Google  4.19
pkehgijcmpdhfbdbbnkijodmdjhbjlgp/2017.11.20_0/manifest.json  __MSG_name__            2017.11.20                   

Upvotes: 0

Views: 292

Answers (2)

ctac_
ctac_

Reputation: 2471

You can try

command | sed 's/[^ ]*/&\t/' | column -ts $'\t'

Upvotes: 1

John1024
John1024

Reputation: 113814

To take the output of some command (which could be your loop) and format it with everything after the first two spaces as being part of one column:

command | sed 's/ /\t/g; s/\t/ /2; s/\t/ /1' input | column -ts' ' | sed 's/\t/ /g'

As an example, consider this file as input:

$ cat input
c1 c2 Eric Clapton
column1 column2 David Crosby
very-long-first-column 2nd Jimi Hendrix Jr

We can generate your desired output via:

$ sed 's/ /\t/g; s/\t/ /2; s/\t/ /1' input | column -ts' ' | sed 's/\t/ /g'
c1                      c2       Eric Clapton
column1                 column2  David Crosby
very-long-first-column  2nd      Jimi Hendrix Jr

How it works

We work on the text in three steps:

  1. sed 's/ /\t/g; s/\t/ /2; s/\t/ /1'

    This replaces all blanks except the first two with tabs.

  2. column -ts' '

    This does column -t formatting but applies it only to blank-separated fields.

  3. sed 's/\t/ /g'

    This converts the tabs in the third column back to blanks.

Shell function for ease-of-use

First, define:

format() { sed 's/ /\t/g; s/\t/ /2; s/\t/ /1' "$@" | column -ts' ' | sed 's/\t/ /g'; }

Now, we can apply the formatting in a quick-and-simple way, either as part of a pipeline:

$ cat input | format
c1                      c2       Eric Clapton
column1                 column2  David Crosby
very-long-first-column  2nd      Jimi Hendrix Jr

Or, operating on a file:

$ format input
c1                      c2       Eric Clapton
column1                 column2  David Crosby
very-long-first-column  2nd      Jimi Hendrix Jr

To make the definition of format permanent, place it in your ~/.bashrc file.

Formatting for N number of columns

Let's define a function that will allow us to specify a number of columns:

frmt() { [[ $1 =~ ^[0-9]+$ ]] && sed "s/ /\t/$1g" "${@:2}" | column -ts' ' | sed 's/\t/ /g'; }

We can format a file for two columns:

$ frmt 2 input
c1                      c2 Eric Clapton
column1                 column2 David Crosby
very-long-first-column  2nd Jimi Hendrix Jr

Or for 3 columns:

$ frmt 3 input
c1                      c2       Eric Clapton
column1                 column2  David Crosby
very-long-first-column  2nd      Jimi Hendrix Jr

We can use the same function as part of a pipeline:

$ cat input | frmt 3
c1                      c2       Eric Clapton
column1                 column2  David Crosby
very-long-first-column  2nd      Jimi Hendrix Jr

This approach uses GNU sed and, consequently, will work on Linux, including ArchLinux, but not on OSX/BSD systems.

Upvotes: 2

Related Questions