Pass arguments from previous commands (pipes) to awk/printf function and format output
Solution 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
- isprintt("%30s",str)
"%.*s",30,str
- isprintt("%.30s",str)
Solution 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
.
Solution 3
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.
Related videos on Youtube
x80486
Denosaur, Gopher — in that order. Erlang deserter 🤣 Web development. Breaking the Internet...one hub at a time. Reading. Thinking. Scuba diving.
Updated on September 18, 2022Comments
-
x80486 over 1 year
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
orprintf
, 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.
-
x80486 almost 6 yearsThanks, 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/orawk
. -
JJoao almost 6 years@ɐuıɥɔɐɯ, please see my edit.
-
x80486 almost 6 yearsOn the same realm, do you know how to place the value of
n
in thesprintf
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 ;) -
JJoao almost 6 years@ɐuıɥɔɐɯ,
awk '{... s=sprintf("%*.s",n,""); ...
-
JJoao almost 6 years@ɐuıɥɔɐɯ, Please see my explanation. You should write your answer :) -- if you used
sort -nr | head
you could use first line to define a "perfect" n. -
x80486 almost 6 yearsThanks for your help! I like better the
sort -nr | head
approach...and also, thiss = sprintf("%*.s", n, "");
works like a charm! I can't upvote your answer more than once ;)