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.

1

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)
  • 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. – x80486 May 14 '18 at 13:21
  • @ɐuıɥɔɐɯ, please see my edit. – JJoao May 14 '18 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 ;) – x80486 May 15 '18 at 0:46
  • @ɐuıɥɔɐɯ, awk '{... s=sprintf("%*.s",n,""); ... – JJoao May 15 '18 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 ;) – x80486 May 15 '18 at 11:01
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

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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