-3

My output after running a program in bash looks like this (two rows, : limiter, four columns of data)

#003:BMW:11:36

#004:Audi:2:35

I would like to convert that to a bash table like this

Number Car ID Cost
#003 BMW 11 36
#004 Audi 2 35

Is it possible to use sed/awk for this? My data doesn't come from a file.

1
  • 4
    Hi and welcome to this site! can you define a table? for what kind of output you are saying table? what is the bash table means? you want replace colon delimiters with Tabs/Spaces?or do you want to build a fixed length lines? please edit your question and clarify these, thanks Commented Nov 13, 2021 at 7:42

3 Answers 3

4

You could use:

process-generating-output | sed '1i Number:Car:ID:Cost\n' | column -s: -t

Outputs:

Number  Car   ID  Cost
#003    BMW   11  36
#004    Audi  2   35

We insert a line with the sed command 1i where we put the column names - separated by colons just as you columns are in your 'process-generating-output'. Then pipe all that through the column command to align it nicely.

(Thanks to @Frédéric Loyer for a better way to insert the column names!)

4
  • That works great! Just one more thing - can I somehow add (alligned) column names? If I used sed command to insert names into the 1st line, the names are not aligned with the columns. Commented Nov 13, 2021 at 7:40
  • @Blaine44 I updated the answer to add column names. There may be a cleaner way to do this, but it works. Commented Nov 13, 2021 at 10:03
  • Using 1s/^/…\n/ to insert a line seems me unnatural. Using 1i… is simpler. Commented Nov 13, 2021 at 11:29
  • @FrédéricLoyer Ah that is nice - I didn't know about the 1i possibility. I've updated the answer. Thanks! Commented Nov 13, 2021 at 12:01
2

Assuming you want to have the data formatted like

| Number | Car  | ID | Cost |
| ------ | ---- | -- | ---- |
| #003   | BMW  | 11 |   36 |
| #004   | Audi |  2 |   35 |

The csvlook command from csvkit does this for you, if you first insert the headers.

You may insert the headers by editing your file (or causing your data-generator command to emit them), adding a line saying Number:Car:ID:Cost at the start, or you may provide the header line on the fly:

$ { echo Number:Car:ID:Cost; cat file; } | csvlook
| Number | Car  | ID | Cost |
| ------ | ---- | -- | ---- |
| #003   | BMW  | 11 |   36 |
| #004   | Audi |  2 |   35 |

Above, the csvlook command detects that the data is a CSV document using : as its field delimiter (this could also be explicitly specified using -d :), and produces the formatted table.

Note that cat file may be replaced by any command producing the data as output.

The final output from csvlook is valid Markdown code which, on this site, renders like this:

Number Car ID Cost
#003 BMW 11 36
#004 Audi 2 35

Treating the input as CSV allows us to support fields containing quoted : characters:

$ cat file
#003:BMW:11:36
#004:Audi:2:35
#005:Saab:99:"1:50"
$ { echo Number:Car:ID:Cost; cat file; } | csvlook
| Number | Car  | ID | Cost |
| ------ | ---- | -- | ---- |
| #003   | BMW  | 11 | 36   |
| #004   | Audi |  2 | 35   |
| #005   | Saab | 99 | 1:50 |
1
  • +1 Goodbye cumbersome vim macros to make markdown tables, hello :!csvlook Commented Nov 13, 2021 at 10:43
2

Pipe the output stream to the next line:

| column -ts: -o$'\t' -N Number,Car,ID,Cost

Perhaps the -o$'\t' (--output-separator) option will need to be omitted.

1
  • column is totally what I was looking for! thx! Commented Aug 10, 2024 at 12:44

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.