Format columns and heads using shell script

My program output text file data in columns format. My problem is the column headers do not align with the data and if filesystem and Mounted On columns pathname are too long the text will not wrap.

Is there any function in Unix that I can use in my code that will align the data for each column with the correct headers? Is there any script in Unix that will wrap text if the pathname is too long?

1) The attachment named data not aligned with column headers shows the
current results.

2) The attachment named how i want the results. Is want I am looking for.

3) The attachment named disk_2016.11.29.txt is the file that is read in the code

here is my code

#!/bin/ksh
 
 
 
fpath=/sas/scripts/OPTUMize/output/disk_utilization
 
# get input
echo "Enter Group name (ex: hasasvmi): "
read gname
 
echo "Enter Current Date( ex: 10/01/2016): "
read cdate
# format: 09/30/2016
 
# parse date
yyyy=$(echo ${cdate} | cut -d"/" -f3)
dd=$(echo ${cdate} | cut -d"/" -f2)
mm=$(echo ${cdate} | cut -d"/" -f1)
 
echo "Enter number of records (ex: 1-1000): "
read nrec
 
# construct file name to parse
diskfile=${fpath}/disk_${yyyy}.${mm}.${dd}.txt
 
# check if file exists
if [ ! -f ${diskfile} ]
then
                echo File: ${diskfile} not found. Exiting.
                exit 1
fi
 
# generate output on screen - TAB separated (OFS)

awk -v gname=${gname} -v OFS="\t" 'BEGIN { print "Filesystem", "blocks", "Free", "% Used", "%Iused", "Mounted on", "Date", "Time" }
$0 ~ gname { gsub(/_/,""'"OFS"'"",$7); print $1, $2, $3, $4, $5, $6, $7 }' ${diskfile} | head -$(expr ${nrec} + 1)

tl;dr the attachments but the printf command, which is implemented by both the shell and awk might be part of the solution of your issue.

Hi.

I've used align for years on a number of platforms. Details are below.

To see demonstrations, search for align drl on this site ... cheers, drl

align   Align columns of text. (what)
Path    : ~/p/stm/common/scripts/align
Version : 1.7.0
Length  : 270 lines
Type    : Perl script, ASCII text executable
Shebang : #!/usr/bin/perl
Help    : probably available with --help
Home    : http://kinzler.com/me/align/
Modules : (for perl codes)
 Getopt::Std    1.10

where would I place align or printf in my code?

printf is a UNIX/Linux command - lives in /usr/bin/printf, on some systems it is part of shell language
The type command is your friend, example in bash shell:

$ type printf
printf is a shell builtin

align is perl code that drl suggests. perl runs under bash like awk does. You feed awk a series of awk syntax lines, it executes. perl is the same.

This shows you how to use align:

It is a short script demo. You have to have the align perl code in your current working directory. It can also be in your PATH variable so the system can find it.

The script example also mentions where to download the perl code from

1 Like

I added sprintf to my code and it doesn't appear to work. I am doing something wrong. I could not figure out how to use align in my code even with the demo.

Here is my code using sprintf. Please tell me what I did wrong.


!/bin/ksh
 
 
 
fpath=/sas/scripts/OPTUMize/output/disk_utilization
 
# get input
echo "Enter Group name (ex: hasasvmi): "
read gname
 
echo "Enter Current Date( ex: 10/01/2016): "
read cdate
# format: 09/30/2016
 
# parse date
yyyy=$(echo ${cdate} | cut -d"/" -f3)
dd=$(echo ${cdate} | cut -d"/" -f2)
mm=$(echo ${cdate} | cut -d"/" -f1)
 
echo "Enter number of records (ex: 1-1000): "
read nrec
 
# construct file name to parse
diskfile=${fpath}/disk_${yyyy}.${mm}.${dd}.txt
 
# check if file exists
if [ ! -f ${diskfile} ]
then
                echo File: ${diskfile} not found. Exiting.
                exit 1
fi
 
# generate output on screen - TAB separated (OFS)

awk -v gname=${gname} -v OFS="\t" 'BEGIN { print "Filesystem", "blocks", "Free", "% Used", "%Iused", "Mounted on", "Date", "Time" }
$0 ~ gname { gsub(/_/,""'"OFS"'"",$7); sprintf $1, $2, $3, $4, $5, $6, $7 }' ${diskfile} | head -$(expr ${nrec} + 1)

Hi.

You connect the output of one program with the input of another, like so:

your-program | ./align

which assumes you have the perl code align in the current directory.

Best wishes ... cheers, drl

The OS is AIX

I tried using your example

grpdsku.sh | ./align

but I get an error message
this is no pipe to read data written to a pipe.

I tried using printf in my code but the headers and columns format disappeared.

I get an error message when I used sprintf in my code:

awk -v gname=${gname} -v OFS="\t" 'BEGIN { sprintf "Filesystem", "blocks", "Free", "% Used", "%Iused", "Mounted on", "Date", "Time" }
$0 ~ gname { gsub(/_/,""'"OFS"'"",$7); sprintf $1, $2, $3, $4, $5, $6, $7 }' ${diskfile} | head -$(expr ${nrec} + 1)
grpdsku.sh | ./align

when I use printf in my code, the headers and columns format disappear:

awk -v gname=${gname} -v OFS="\t" 'BEGIN { printf "Filesystem", "blocks", "Free", "% Used", "%Iused", "Mounted on", "Date", "Time" }
$0 ~ gname { gsub(/_/,""'"OFS"'"",$7); printf $1, $2, $3, $4, $5, $6, $7 }' ${diskfile} | head -$(expr ${nrec} + 1)

Hi.

For a system like:

aix 7.1.0.0
bash GNU bash 4.2.10
align 1.7.0
perl 5.10.1
$ echo -e "hi world\nbye cruel" | ./align

produces

hi  world
bye cruel

Best wishes ... cheers, drl

awk 's sprintf is used to supply formatted strings or (partial) lines of text for variable assignments or printouts, not for printing itself.
Both (s)printf versions need a format string as the first parameter which you fail to provide in your samples.

I tried many ways but nothing appears to work

Without seeing the "many ways" we can't pin the points of failure in either, I'm afraid.

EDIT:
Howsoever, what about sth along this line:

awk -v gname=hasasvmi -v OFS="\t" '
BEGIN           {FMT = "%-20s\t%6s\t%4s\t%6s\t%6s\t%16s\t%10s\t%8s\n"
                 printf FMT, "Filesystem", "blocks", "Free", "% Used", "%Iused", "Mounted on", "Date", "Time"
                }

$0 ~ gname      {split ($7, T, /_/)
                 printf FMT, $1, $2, $3, $4, $5, $6, T[1], T[2] 
                }
' /tmp/disk_2016.11.29.txt 
Filesystem          	blocks	Free	% Used	%Iused	      Mounted on	      Date	    Time
/dev/sasdwk/hasasvmi	   128	   1	   127	    0%	/sasdwk/hasasvmi	2016.11.29	00.00.31
/dev/sasdd1/hasasvmi	   256	  44	   212	17.00%	/sasdd1/hasasvmi	2016.11.29	00.00.34
/dev/sasdwk/hasasvmi	   128	   1	   127	    0%	/sasdwk/hasasvmi	2016.11.29	00.30.40
.
.
.