KaanEm
KaanEm

Reputation: 31

Shell Script output formatting echo

I have output from a shell script like below

##########################################################
Creation date: 15-03-2022 / 15:03
performed by: user
Environment: E_MTE_04
Reference - Repository: TEST
-BSL Number of documents: XXX
-Syr Number of documents: XXX
-DEB Number of documents: XXX
Candidate - Repository: TEST
-BSL Number of documents: XXX
-Syr Number of documents: XXX
-DEB Number of documents: XXX

I tried to format it with equal spacing inside script but output still not have uniform spacing. I want to print the output like below.

##########################################################
Creation date:                     15-03-2022 / 15:03
performed by:                      user
Environment:                       E_MTE_04
Reference - Repository:            TEST
-BSL Number of documents:          XXX
-Syr Number of documents:          XXX
-DEB Number of documents:          XXX
Candidate - Repository:            TEST
-BSL Number of documents:          XXX
-Syr Number of documents:          XXX
-DEB Number of documents:          XXX

Are there any commnads available to get this done. I use bash. here is the code.

echo "##########################################################" >> $log
echo Creation date: $today" / $time">> $log
echo performed by: $USER >> $log
echo Environment: $firstEnv >> $log
echo Reference - Repository: $firstParamomsID >> $log
echo -BSL Number of documents: XXX >> $log
echo -Syr Number of documents: XXX >> $log
echo -DEB Number of documents: XXX >> $log
echo Candidate - Repository: $secondParamomsID >> $log
echo -BSL Number of documents: XXX >> $log
echo -Syr Number of documents: XXX >> $log
echo -DEB Number of documents: XXX >> $log

Thanks

Upvotes: 1

Views: 10585

Answers (4)

Pierre
Pierre

Reputation: 580

You can also use the column utility, as follows:

#!/usr/bin/bash

# A few variables, just so that I can view what's going on here:
log=/tmp/toto
today=$(date -I)
time=$(date +%H:%M)
USER="user"
firstEnv="E_MTE_04"
firstParamomsID=TEST
secondParamomsID="TEST"

# First decoration line:
echo "##########################################################" >> ${log}

# Start with a temporary variable:
tmp=""

# Build that variable by appending strings, with a newline (\n) 
# every time; the trick is to insert a special character where you
# want column separators; in this example I chose "|":
tmp+="\nCreation date:|${today} / ${time}"

# Another trick is to add a few extra spaces before the column on 
# one line, so that the output will be more widely distributed;
# this can be done on any line, I just made it on the following one:
tmp+="\nperformed by:                    |${USER}"

# Keep on building the ${tmp} string:
tmp+="\nEnvironment:|$firstEnv"
tmp+="\nReference - Repository:|${firstParamomsID}"
tmp+="\n-BSL Number of documents:|XXX"
tmp+="\n-Syr Number of documents:|XXX"
tmp+="\n-DEB Number of documents:|XXX"
tmp+="\nCandidate - Repository:|${secondParamomsID}"
tmp+="\n-BSL Number of documents:|XXX"
tmp+="\n-Syr Number of documents:|XXX"
tmp+="\n-DEB Number of documents:|XXX"

# Now that the ${tmp} string is built, let's process it:
echo -e "${tmp}" | column -s "|" -t >> ${log}

The magic is done by column on the last line.

And here is the output that I get:

 # pierre@latitude: ~ < 2023_11_04__17_17_27 > [bashpid_24830 19]
tail -12 /tmp/toto 
##########################################################
Creation date:                     2023-11-04 / 17:17
performed by:                      user
Environment:                       E_MTE_04
Reference - Repository:            TEST
-BSL Number of documents:          XXX
-Syr Number of documents:          XXX
-DEB Number of documents:          XXX
Candidate - Repository:            TEST
-BSL Number of documents:          XXX
-Syr Number of documents:          XXX
-DEB Number of documents:          XXX

Note that I systematically surrounded variables by {}; it is a good practice, some colleagues are saying.

Upvotes: 0

markp-fuso
markp-fuso

Reputation: 33984

Assuming you can change the script, one idea would be to replace the echo calls with printf, eg:

Setup:

today='15-03-2022'
time='15:03'
USER=user
firstEnv='E_MTE_04'
firstParamomsID='TEST'
secondaryParamomsID='TEST'

Our printf format string:

fmt="%-30s %s\n"

Where:

  • %-30%s - print the 1st argument in a left-justified field of width 30
  • %s\n - print 2nd argument followed by a linefeed

Replacing current echo code looks like:

echo "##########################################################"
printf "${fmt}" "Creation date:" "${today} / ${time}"
printf "${fmt}" "performed by:" "${USER}"
printf "${fmt}" "Environment:" "${firstEnv}"
printf "${fmt}" "Reference - Repository:" "${firstParamomsID}"
printf "${fmt}" "-BSL Number of documents:" "XXX"
printf "${fmt}" "-5yr Number of documents:" "XXX"
printf "${fmt}" "-DEB Number of documents:" "XXX"
printf "${fmt}" "Candidate - Repository:" "${secondaryParamomsID}"
printf "${fmt}" "-BSL Number of documents:" "XXX"
printf "${fmt}" "-5yr Number of documents:" "XXX"
printf "${fmt}" "-DEB Number of documents:" "XXX"

If all of the printf calls are on consecutive lines (ie, no other code between the lines) you can use a single printf to process all strings; printf will re-apply $fmt until it exhausts the list of input strings, eg:

echo "##########################################################"
printf "${fmt}" "Creation date:"            "${today} / ${time}" \
                "performed by:"             "${USER}" \
                "Environment:"              "${firstEnv}" \
                "Reference - Repository:"   "${firstParamomsID}" \
                "-BSL Number of documents:" "XXX" \
                "-5yr Number of documents:" "XXX" \
                "-DEB Number of documents:" "XXX" \
                "Candidate - Repository:"   "${secondaryParamomsID}" \
                "-BSL Number of documents:" "XXX" \
                "-5yr Number of documents:" "XXX" \
                "-DEB Number of documents:" "XXX"

NOTE: the extra spacing (beginning of lines, between args) is optional; I've added the extra spaces to improve readability

Both of these generate:

##########################################################
Creation date:                 15-03-2022 / 15:03
performed by:                  user
Environment:                   E_MTE_04
Reference - Repository:        TEST
-BSL Number of documents:      XXX
-5yr Number of documents:      XXX
-DEB Number of documents:      XXX
Candidate - Repository:        TEST
-BSL Number of documents:      XXX
-5yr Number of documents:      XXX
-DEB Number of documents:      XXX

Upvotes: 1

chepner
chepner

Reputation: 530872

Use tabs to separate columns, then use the standard expand utility to expand tabs using spaces. For example,

printf '%s\t%s\n' "Creation date:" "15-03-2022 / 15:03" \
                  "performed by: " "user" \
                  "Environment: " "E_MTE_04" |
  expand -t 20

produces

Creation date:      15-03-2022 / 15:03
performed by:       user
Environment:        E_MTE_04

The only thing you need to do is ensure the tab stops specified by the -t option are large enough to accommodate the longest string in each column.

Upvotes: 1

OldManSeph
OldManSeph

Reputation: 2699

Add the spaces between the label and the variable

Change:

echo Creation date: $today" / $time">> $log

To:

echo Creation date:                     $today" / $time">> $log

Upvotes: 0

Related Questions