Operating System - HP-UX
1822494 Members
2417 Online
109642 Solutions
New Discussion юеВ

How to align the space between column in output of the script.

 
SOLVED
Go to solution
senthil_kumar_2
Regular Advisor

How to align the space between column in output of the script.

I am using following script to view home folder (/emd/home) size of the users.

My script file:


#! /usr/bin/sh
cd /emd/home
echo "SPACE \t \t USERID \t \t USERNAME \t \t LINKED DIRECTORY \n"
du -sk * | sort -rn | while read line
do
space=`echo $line | awk {'print $1'}`
uname=`echo $line | awk {'print $2'}`
givenname=`grep ^"$uname:" /etc/passwd|cut -d: -f5`
linkdir=`ll -nd /emd/home/$uname | awk {'print $11'}`
#homedir=$(echo /emd/home/$uname)
echo "$space \t \t $uname \t \t $givenname \t \t $linkdir"
done


The output is: (Pls find the attachment)

SPACE USERID USERNAME LINKED DIRECTORY

7468504 remoquil Soliman Remoquillo,,,
5806088 pzhysl Jason Meyers,,,
3069352 7en0fm Mark Herman
0584 oddie Michael Oddie,,,
3336 bin
3288 hzrwh7 Michell Westra,,,
3080 xz5v8v Seban, Elizabeth,,
5176 deano Dean Linko,,,
4608 czhk53 Vijay Reddy,,,
3072 zz7msk Mike Miller,,,
2880 erickson Karl Erickson,,,
1648 test7 Testin ID
7680 security
7296 andersos Steven Anderson,,,
6152 3ezaxv Colin Copley
5936 noel Doug Noel,,,
4512 src
4304 xz9wmt Rajkumar Molugu,,,
0 vz1fmk Ish Patel,,,
0 tzrrzp Roopesh Shroff,,, /emd/ansys2/tzrrzp
0 tpw /emd/tpw
0 tombers /emd/ansys1/tombers
0 svihla Gary Svihla,,, /emd/ansys2/svihla
0 stdlib Standards Coord CDMS,,, /users/stdlib
0 schueler /emd/ansys2/schueler
0 rz17by Maximo Test,,,
0 ne7jll Lindsay Parsons,,,
0 ley7ux Sridhar Chunduri
0 kzx4yz Greg Langlois,,,
0 kmoravec Keith Moravec,,, /emd/ansys1/kmoravec
0 jyu Jin Yu,,, /emd/ansys1/jyu
0 jcarr John Carr,,, /emd/ansys2/jcarr
0 fkankuc Fanny Kanku,,,
0 duve /emd/ansys1/duve
0 cp
0 chobot Tony Chobot,,, /emd/ansys1/chobot



Pls find the attachment for the current align ment of the above output.
25 REPLIES 25
James R. Ferguson
Acclaimed Contributor

Re: How to align the space between column in output of the script.

Hi Senthil:

If you want consistent columnar alignment, use 'printf' with fixed widths and not tab ('\t') characters in an 'echo' statement.

Regards!

...JRF...
Kenan Erdey
Honored Contributor
Solution

Re: How to align the space between column in output of the script.

Hi,

try this line instead of echo:

printf "%-20s%-20s%-20s%-20s\n" "$space" "$uname" "$givenname" "$linkdir"
Computers have lots of memory but no imagination

Re: How to align the space between column in output of the script.

Hi, Senthil

I use awk's "printf" function for that (that's pretty much the same a the shell's one suggested by James).

I took your script and rewrited:
#! /usr/bin/sh
(
cd /emd/home
echo "SPACE USERID USERNAME LINKED_DIRECTORY"
du -sk * | sort -rn | while read space uname
do
# space=`echo $line | awk {'print $1'}`
# uname=`echo $line | awk {'print $2'}`
givenname=`grep ^"$uname:" /etc/passwd|cut -d: -f5`
linkdir=`ll -nd /emd/home/$uname | awk {'print $11'}`
echo "$space $uname $givenname $linkdir"
done
)| awk '{printf "%10s %-10s %-15s %s\n", $1, $2, $3, $4}'

Changes: the "read" command can split the input line (no need for the extras "awk" to extract uname y space)

The "echo" lines prints the data with just a single space, the final awk would do all de formating. All echo's go to the same awk as they're within a subshell (bettween parenthesis). All subshell output goes to the final pipe where awk read id.

With this schema is simple to adust the script for varying lenghts in some field, to left o right justify. And, as title and body are processed by the same line, they're always be coherent.

Hope it helps. On my system worked pretty well (see attatch)

Re: How to align the space between column in output of the script.

forgot the attatch
Hein van den Heuvel
Honored Contributor

Re: How to align the space between column in output of the script.

First a small comment>>

"The output is: (Pls find the attachment)"

Good and appreciated attempt, but it is not the actual output. Is appears to be a cut & paste from a screen shot with the TAB characters which are critital to this problem gratuitously, and erroneously, transformed to spaces. To do this properly, redirect to a file and transfer as 'txt'. (Not .DOC not .RTF !).

Anyway... If you are doing all this awking and grepping, then why pretend to write a shell script. Just write a full awk program ?!
Get in there once, make it do the job, and get out.

You see, I'm a performance guy. So I cringe when I see "grep uname passwd | cut -d: -f5"
in a loop. For every record processed we read a whole file, and spawn two processes. Read it once, and remember what you need to!
:-)

The output format ought to the same for the header and a details right? A single awk program can nicely accomplish that.

So where is this rambling leading to?
Check out the program 'test.awk' below.

It reads /etc/passwd in the "BEGIN" section and fills an array with username -> given-name associations. That section also defines the output format and prints the header.

In the main loop, we look up the username, lookup your directory link, and print the output. Easy?

Run as:
du -sk * | sort -rn | awk -f test.awk > test.txt

Results in test.txt:

SPACE USERID USERNAME LINKED
----- ------ -------- ------
71864 hein Hein van den Heuvel /home/hein/aap
2352 test /home/hein/noot


Enjoy !
Hein.


BEGIN { FS = ":";
while (getline < "/etc/passwd") u[$1] = $5;
FS = " ";
fmt = "%12s %-12s %-20s %-30s\n"
printf fmt, "SPACE", "USERID", "USERNAME", "LINKED", "DIRECTORY";
printf fmt, "-----", "------", "--------", "------", "---------";
}

{ space = $1;
uname = $2;
given = u[uname];
"ll -nd /emd/home/" uname | getline;
link = $11;
printf fmt, space, uname, given, link;
}




James R. Ferguson
Acclaimed Contributor

Re: How to align the space between column in output of the script.

Hi (again):

...and this thread would appear to be a continuation of your earlier one:

http://forums.itrc.hp.com/service/forums/questionanswer.do?threadId=1341889

Regards!

...JRF...
Suraj K Sankari
Honored Contributor

Re: How to align the space between column in output of the script.

Hi,

Instead of this below line or your script
echo "$space \t \t $uname \t \t $givenname \t \t $linkdir"

use this line into your script
printf "%-15s %20s %20s %20s" $space $uname $givenname $linkdir

Suraj
senthil_kumar_2
Regular Advisor

Re: How to align the space between column in output of the script.

Hi Friends,

I modified the script as per your suggestion. now i am able to get the output aligned.

Modified script is:

#! /usr/bin/sh

cd /emd/home
printf "%-10s %-15s %-35s %-25s\n" "SPACE" "USERID" "USERNAME" "LINKED_DIRECTORY"
printf "%-10s %-15s %-35s %-25s\n" "-----" "------" "--------" "----------------"
du -sk * | sort -rn | while read space uname
do
#space=`echo $line | awk {'print $1'}`
#uname=`echo $line | awk {'print $2'}`
givenname=`grep ^"$uname:" /etc/passwd|cut -d: -f5`
linkdir=`ll -nd /emd/home/$uname | awk {'print $11'}`

printf "%-10s %-15s %-35s %-25s\n" "$space" "$uname" "$givenname" "$linkdir"
done


My output is:

SPACE USERID USERNAME LINKED_DIRECTORY
----- ------ -------- ----------------
7468504 remoquil Soliman Remoquillo,,,
5806312 pzhysl Jason Meyers,,,
3069352 7en0fm Mark Herman
2033224 wabtec Wabtec sharedaccount,,,
1966224 paez
1961688 7e8e9u Steven Dettloff,,,
1888472 mentordata
1810456 infodba Iman Administrator,,,
1650224 tek
1536368 reydl2 Matthew A Sawtell,,,
269904 common_box
0 zzw2cc Cherl Nordmann,,,
0 zehjrf
0 vzh53p Walter Klaric,,,
0 vz1fmk Ish Patel,,,
0 tzrrzp Roopesh Shroff,,, /emd/ansys2/tzrrzp
0 tpw /emd/tpw
0 tombers /emd/ansys1/tombers
0 svihla Gary Svihla,,, /emd/ansys2/svihla
0 stdlib Standards Coord CDMS,,, /users/stdlib


Here i want one more to be done.

In username column of the report is displaying the 5th column (GECOS) of the "/etc/passwd".

Previous unix admin of our company userd to give three commas (,,,) after each names mentioed in the 5th column (comment field) of the passwd file.

Now i want to remove commas (,,,) if it is suffixed with the name.

Here I want the name only but not commas.

Pls give your suggestion on modifying the script.



I have attached the file containing my script and output report.
James R. Ferguson
Acclaimed Contributor

Re: How to align the space between column in output of the script.

Hi:

To eliminate the commas from your output, add the following line just before your 'printf':

# givenname=$(echo "${givenname}"|sed -e 's/,/ /g')

This replaces every comma character with a space. Thus if there is more than just the first field of the GECOS field, other subfields are left space-delimited.

Regards!

...JRF...


Kenan Erdey
Honored Contributor

Re: How to align the space between column in output of the script.

hi,

change givenname as :

givenname=`grep ^"$uname:" /etc/passwd|cut -d: -f5` | sed -e 's/,//g'


Computers have lots of memory but no imagination
Sunny123_1
Esteemed Contributor

Re: How to align the space between column in output of the script.

Hi
try this

givenname=$(echo "${givenname}"|sed -e 's/,/ /g')

Regards
Sunny
Viktor Balogh
Honored Contributor

Re: How to align the space between column in output of the script.

i prefer Hein's solution too, there are a lot of 'heavy' shell commands piped together, and the performance suffers this way. IMHO the best way would be to write it all in awk...

Hein, nice coding! But can we call this
"du -sk * | sort -rn" thing inside of awk? ;)

****
Unix operates with beer.
Suraj K Sankari
Honored Contributor

Re: How to align the space between column in output of the script.

Hi,

>>Here I want the name only but not commas

There are 2 easy way to remove comma
1. open your output into vi
at the vi command prompt give this
:1,$s/,,,//gp

2. assum your output is in out.txt file
now give this command at comman prompt
#sed 's/,,,//'
Suraj
Dennis Handly
Acclaimed Contributor

Re: How to align the space between column in output of the script.

>Viktor: But can we call this "du -sk * | sort -rn" thing inside of awk? ;)

Yes but why bother. ;-)
"du -sk *" | getline
senthil_kumar_2
Regular Advisor

Re: How to align the space between column in output of the script.

Hi Friends,

Thanks a lot now i am getting correct output that i want.

But some entries are repeating, i want to retain only one entry for each. so how to truncat the other entry.

A)My script:

#! /usr/bin/sh

cd /emd/home
printf "%-10s %-15s %-35s %-25s\n" "SPACE" "USERID" "USERNAME" "LINKED_DIRECTORY"
printf "%-10s %-15s %-35s %-25s\n" "-----" "------" "--------" "----------------"
du -sk * | sort -rn | while read space uname
do
#space=`echo $line | awk {'print $1'}`
#uname=`echo $line | awk {'print $2'}`
givenname=`grep ^"$uname:" /etc/passwd|cut -d: -f5|sed 's/,//g'`
linkdir=`ll -nd /emd/home/$uname | awk {'print $11'}`

printf "%-10s %-15s %-35s %-25s\n" "$space" "$uname" "$givenname" "$linkdir"
done


B)Output:


SPACE USERID USERNAME LINKED_DIRECTORY
----- ------ -------- ----------------
7436064 remoquil Soliman Remoquillo
5806320 pzhysl Jason Meyers
3069352 7en0fm Mark Herman
2033224 wabtec Wabtec sharedaccount
2032944 7e8e9u Steven Dettloff
1966224 paez
1888472 mentordata
1810456 infodba Iman Administrator
1650224 tek
1536368 reydl2 Matthew A Sawtell
1443248 redquest
1381032 nzr3k0 Nicholas Shim-Ping
103832 lzrxcl Emma Biddings ---------------------------> First time
Emma Biddings ------------------------------------------------------> second time
6544 oracle Oracle Administrator --------------------> First time
Oracle Administrator -----------------------------------------------> Second time
0 vz1fmk Ish Patel
0 tzrrzp Roopesh Shroff /emd/ansys2/tzrrzp
0 tpw /emd/tpw
0 tombers /emd/ansys1/tombers
0 svihla Gary Svihla /emd/ansys2/svihla
0 stdlib Standards Coord CDMS /users/stdlib
0 schueler /emd/ansys2/schueler
0 rz17by Maximo Test


C)I checked why they are comming two times:


1) 103832 lzrxcl Emma Biddings
Emma Biddings

root@lgapps:/root > grep lzrxcl /etc/passwd

lzrxcl:R1b5gn01B1VGU:1260:1002:Emma Biddings,,,:/emd/ansys2/lzrxcl:/usr/bin/sh
lzrxcl:R1b5gn01B1VGU:1260:1002:Emma Biddings,,,:/emd/ansys2/lzrxcl:/usr/bin/sh


2)6544 oracle Oracle Administrator
Oracle Administrator

root@lgapps:/root > grep ^oracle: /etc/passwd

oracle:oAx6JjE54AHZw:498:1010:Oracle Administrator,,,:/appl/oracle/dba/admin:/usr/bin/sh
oracle:oAx6JjE54AHZw:498:1010:Oracle Administrator,,,:/appl/oracle/dba/admin:/usr/bin/sh


I want only one entry for each directory.

Pls find the attachment for clear details.

Sunny123_1
Esteemed Contributor

Re: How to align the space between column in output of the script.

Hi

Can you attached it once again????


Regards
Sunny
Dennis Handly
Acclaimed Contributor

Re: How to align the space between column in output of the script.

>Pls find the attachment for clear details.

Thanks, that solves the mystery:
givenname=$(grep "^$uname:" /etc/passwd |
awk -F: 'NR == 1 { gsub(",", "", $5); print $5 }')

(Or you could stick a "head -1" in the pipe.)
Sunny123_1
Esteemed Contributor

Re: How to align the space between column in output of the script.

Hi

You can give head option in pipe like

head -1 if you want only one entry.

Regards
Sunny
senthil_kumar_2
Regular Advisor

Re: How to align the space between column in output of the script.

Hi All,

Thanks a lot.

Now everything is fine.


Sunny123_1
Esteemed Contributor

Re: How to align the space between column in output of the script.

Hi Senthil

If you got proper solution please go ahead and closed this thread

Regards
Sunny
Hein van den Heuvel
Honored Contributor

Re: How to align the space between column in output of the script.

Senthil>> But some entries are repeating, i want to retain only one entry for each. so how to truncat the other entry.

The details provided show that this is caused by duplicate entries in /etc/passwd. The solution (IMHO) is to fix that instead of using some workaround in your script. Fix the core problem for all!


I must admit to a weakness in my suggested solution approach. As written it does not report trying to enter a username entry when one exists. It would have worked without alerting you to the problem with /etc/password.

Viktor>> Hein, nice coding! But can we call this
"du -sk * | sort -rn" thing inside of awk? ;)

Thank you!. I try. As Dennis says, yeah you could, but why. I preferred to keep is outside as it seemed to me that it woudl be the most variable part. It allows you to drive the same report with different data sources. Maybe sorted differently, maybe cobbled up together from multiple intermediate files.

fwiw,

Hein.


James R. Ferguson
Acclaimed Contributor

Re: How to align the space between column in output of the script.

Hi:

Dennis suggested:

# givenname=$(grep "^$uname:" /etc/passwd |
awk -F: 'NR == 1 { gsub(",", "", $5); print $5 }')

...but I so dislike 'grep' piped to 'awk' --- as it uses an extra process (the 'grep') when 'awk' can do it all! Hence:

# givenname=$(awk -F: -v uname=${uname} '$1~uname {gsub(",","",$5);print $5}' /etc/passwd)

...which enables exact matches and eliminates the need for a 'tail -1' or testing for one record in the 'awk' too!

By the way, I also dislike using 'uname' as a variable name since it is the name of a command.

Regards!

...JRF...
Dennis Handly
Acclaimed Contributor

Re: How to align the space between column in output of the script.

>JRF: but I so dislike 'grep' piped to 'awk'

Oops, spent so much time removing cut, sed and head, forgot about grep.

>eliminates the need for a 'tail -1' or testing for one record in the 'awk' too!

Why do you say that? If /etc/passwd has two identical records, your script will find both.
Easily fixed by:
givenname=$(awk -F: -v uname=${uname} '$1 ~ uname {gsub(",","",$5); print $5; exit}' /etc/passwd)
James R. Ferguson
Acclaimed Contributor

Re: How to align the space between column in output of the script.

Hi (again):

> Dennis: If /etc/passwd has two identical records, your script will find both.

Ah, now I see what you were originally saying. Senthil's 'passwd' file actually has identical account name records. My comment was focused on the fact that we would match exactly on account name; not that there might be multiple instances. I agree that an 'exit' in the 'awk' after a match is the most performance satisfactory solution. Using a piped 'tail' merely adds another process.

> Senthil, I would 'vipw' your 'passwd' file and _eliminate_ the duplicate accounts. Unfortunately running 'pwck' will not uncover them.

> Dennis > JRF: but I so dislike 'grep' piped to 'awk'. Oops, spent so much time removing cut, sed and head, forgot about grep.

That's OK, you found a similar one that I had missed for the same reason in another thread :-}}

Regards!

...JRF...