0

Eg. Processes being run by various users are as below.

root 5
xuser 3
yuser 1

Then the script should give the output as:

root .....
xuser ...
yuser .
1

You can use bash printf and tr to do this histogram:

while read name num; do 
    dots=$(printf "%*s" $num " " | tr " " .)
    printf "%s\t%s\n" "$name" "$dots"
done <<END
root 5
xuser 3
yuser 1
END
root    .....
xuser   ...
yuser   .
  • This worked. The only issue is the output dots(.) are not in arranged manner vertically. xrdp . avahi .. mssql .. dd-agent ... smmsp ... www-data ..... hadoop ...... postgres ...... ideauser ......... pritam.+ ......... gdm ................ Thanks – Prashant Shetage Jun 5 '18 at 5:42
  • You can pipe to | column -t your better alignment – glenn jackman Jun 5 '18 at 10:03
  • Thank Glenn. Your suggestions helped me a lot. My final script which worked perfectly is as below. Please let me know if I can optimise the same. #!/bin/bash cd /home/pi/Desktop/p t=1 while [ $t -lt 6 ] do echo "\n" echo "Occurance $t" ps axo user:10 | sort | uniq -c | sort -n | awk '{print $2,$1}' | while read user process do dots=$(printf "%*s" $process " " | tr " " .) printf "%-10s\t%s\n" "$user" "$dots" done t=$((t+1)) echo "\n" sleep 5s done – Prashant Shetage Jun 7 '18 at 6:38
  • A slightly simpler version for dots generation: dots=$(printf ".%.0s" $(seq 1 $num)) – kaliko Jun 7 '18 at 13:26
0

Using Perl, and assuming that the data is located in file:

$ perl -ne '/^(\w+)\s+(\d+)$/ && printf("%s\t%s\n", $1, "." x $2)' file
root    .....
xuser   ...
yuser   .

You may also apply this on a data stream:

somecommand | perl -ne '...as above...'

The Perl script matches the initial string and the number in the input, and the outputs the string and the appropriate number of dots, with a tab character in-between.


With a bit of tweaking of the above (to be able to read uniq -c output, which has the number first), the following would get the number of processes running for each user and display the counts as dots:

$ ps -ax -o user= | sort | uniq -c | perl -ne '/^\s*(\d+)\s+(\w+)$/ && printf("%-10s%s\n", $2, "." x $1)'
_dbus     .
_dhcp     .
_ntp      ..
_pflogd   .
_slaacd   ..
_smtpd    .....
_smtpq    .
_syslogd  .
_unbound  .
kk        ................
root      ..........................

The ps command might need modification to output the correct thing on Linux (I'm using OpenBSD here, but it seems to do the right thing on Ubuntu too). The Perl script has changed from the first variation so that it properly reads uniq -c output and it formats the lines to allow for usernames of length 10 or less.

Not the answer you're looking for? Browse other questions tagged or ask your own question.