Home > Mobile >  How to format cat command as a table in bash
How to format cat command as a table in bash

Time:11-08

I have the following code that parses XML to display the node value of each element in a file.

#Abbreviation - symbol
cat elements/*.xml |  egrep "<symbol>.*</symbol>" |sed -e "s/<symbol>\(.*\)<\/symbol>/\1/"|tr "|" " "

#Weight - atomic-weight
cat elements/*.xml |  egrep "<atomic-weight>.*</atomic-weight>" |sed -e "s/<atomic-weight>\(.*\)<\/atomic-weight>/\1/"|tr "|" " "

#Number atomic-number
cat elements/*.xml |  egrep "<atomic-number>.*</atomic-number>" |sed -e "s/<atomic-number>\(.*\)<\/atomic-number>/\1/"|tr "|" " " > number

How can I format the three of these outputs as a table instead of one huge sequential list?

Sample Data -

File1 -

  <symbol>Ag</symbol>
  <atomic-number>47</atomic-number>
  <atomic-weight>107.8682</atomic-weight>

File2 -

  <symbol>Ba</symbol>
  <atomic-number>56</atomic-number>
  <atomic-weight>137.327</atomic-weight>

Desired Output -

Symbol   Number   Weight
Ag       47       107.8682
Ba       56       137.327

CodePudding user response:

Try this:

#!/bin/bash

printf '%-9s %-9s %-9s\n' "Symbol" "Number" "Weight"

for F in *.xml
do
    symbol=$(grep -E "<symbol>.*</symbol>" "$F"               | sed -e "s/.*<symbol>\(.*\)<\/symbol>.*/\1/")
    number=$(grep -E "<atomic-number>.*</atomic-number>" "$F" | sed -e "s/.*<atomic-number>\(.*\)<\/atomic-number>.*/\1/")
    weight=$(grep -E "<atomic-weight>.*</atomic-weight>" "$F" | sed -e "s/.*<atomic-weight>\(.*\)<\/atomic-weight>.*/\1/")

    printf '%-9s %-9s %-9s\n' "$symbol" "$number" "$weight"
done
  • printf allows you to format the width and alignment in that width of printed text (or number, or floats, ...).
  • to avoid any interpretation of weight values (i.e. number of decimals for example), all values are printed as strings.
  • for printf, '%-9s' means it will print the value using 9 chars wide, left aligned. Without the -, it will align right.
  • printf does not output a carriage return unless you tell it to, which explains the \n.
  • I reused your grep ... | sed ... commands, but for 2 details. 1 Used grep -E instead of egrep. 2 Added .* at the beginning and end of your sed to eliminate prefixes or suffixes to the <SOMETHING> tags.

The output I get is:

$ ./so.bash 
Symbol    Number    Weight   
Ag        47        107.8682 
Ba        56        137.327  
  • Related