0

I'm trying to filter the most used commands and print that out in a certain way. So far, I've managed to put the desired "filters":

$ history | tr -s ' ' | cut -d ' ' -f3 | sort | uniq -c | sort -n | tail | awk '{ printf "%s%20s\n", $2, $1 }'

...but I can't get the output correctly.

I would like to be able to display the final output like:

checkupdates        16 ▄▄▄
find                16 ▄▄▄
./gradlew           17 ▄▄▄
./rebar3            21 ▄▄▄▄
nix-env             24 ▄▄▄▄
cd                  26 ▄▄▄▄▄
docker              33 ▄▄▄▄▄▄
rebar3              43 ▄▄▄▄▄▄▄▄
sudo                46 ▄▄▄▄▄▄▄▄▄
flatpak             56 ▄▄▄▄▄▄▄▄▄▄▄

I want to use awk or printf, but I can't figure it out how to format the output. Also, it's tricky to manage the space between the command(s) and the next column (the usage numbers) ‒ the third one is just one space away from the second one.


PS: The scale for the ▄ can be anything.

3 Answers 3

2

I think you are looking for xargs for the first part. For example:

$ echo foo bar| xargs printf "- %s - %s -\n"
- foo - bar -

To pad and left adjust the output of printf you can do something like:

$ echo foobar 19 | xargs printf '%-30s %s'
foobar                         19

To make certain that the formatting adapts to the longest command name, and to create the bar, you will probably have to write something more complicated that checks the length of the longest argument on the first column, and then doesn't print the results until it has read all the input, for example using awk.

1

With the help of @JJoao, this is what I came up with later on:

$ history | tr -s ' ' | cut -d ' ' -f3 | sort | uniq -c | sort -nr | head | awk '{ printf "%-25s %-4d", $2, $1, n = $1 / 5; s = sprintf("%*.s", n, ""); gsub(/ /, "◼", s); print s }'
history                   227 ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼
./rebar3                  30  ◼◼◼◼◼◼
cat                       26  ◼◼◼◼◼
cd                        24  ◼◼◼◼
docker                    21  ◼◼◼◼
ps                        20  ◼◼◼◼
bin/erlang_cowboy         19  ◼◼◼
sudo                      13  ◼◼
nix-env                   8   ◼
nix-channel               8   ◼

Not a "big deal", but something I need at work...in case somebody needs it later on.

0

Following PO's approach, replace awk by Perl -- 'Perl -ae' is very similar to awk...

... | perl -ae ' printf "%-20s %d %s\n", $F[0], $F[1],"▄"x$F[1]'
aa                  12 ▄▄▄▄▄▄▄▄▄▄▄▄
bb                  23 ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄

Edit: with Awk, you could run something along the lines of

... | awk '{printf "%-20s %d %.*s\n",$1,$2,$2,"▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"}'

printf function formats (used in C, Awk, Perl, printf command, etc) can be a little tricky. Following some examples with strings:

  • "%.20s,str - width=max(20,len(str)), align=left
  • "%20s",str - width=max(20,len(str)), align=rigth
  • "%.20s",str - width=min(20,len(str)), truncates if len>20
  • "%20.20s,str - width=20 , truncates if len>20, align=right
  • "%*s",30,str - is printt("%30s",str)
  • "%.*s",30,str - is printt("%.30s",str)
6
  • Thanks, but currently I can't use Perl since it is not installed in the server I'm going to run this. I think I'm going to leave out the bars part for the moment. I'll take this solution if nobody chime in with something in bash and/or awk.
    – user280674
    Commented May 14, 2018 at 13:21
  • @ɐuıɥɔɐɯ, please see my edit.
    – JJoao
    Commented May 14, 2018 at 22:58
  • On the same realm, do you know how to place the value of n in the sprintf function for this command: history | tr -s ' ' | cut -d ' ' -f3 | sort | uniq -c | sort -n | tail | awk '{ printf "%-25s %-4d", $2, $1, n = $1 / 12; s = sprintf("%($n)s", ""); gsub(/ /, "◼", s); print s }'. I did try $(n), but that didn't do anything ;)
    – user280674
    Commented May 15, 2018 at 0:46
  • @ɐuıɥɔɐɯ, awk '{... s=sprintf("%*.s",n,""); ...
    – JJoao
    Commented May 15, 2018 at 7:18
  • 1
    Thanks for your help! I like better the sort -nr | head approach...and also, this s = sprintf("%*.s", n, ""); works like a charm! I can't upvote your answer more than once ;)
    – user280674
    Commented May 15, 2018 at 11:01

You must log in to answer this question.