My package manager has a option --dry-run
or -n
that shows what packages will be installed when I do a update -u
.
It outputs in the following format <pkgver> <action> <arch> <repository> <installedsize> <downloadsize>
,
~ $ xbps-install -un | head -n 5
MesaLib-devel-20.1.4_1 update x86_64 https://alpha.de.repo.voidlinux.org/current 148212 35909
amdvlk-2020.Q3.2_1 update x86_64 https://alpha.de.repo.voidlinux.org/current 53003388 17077076
audacious-4.0.5_1 configure x86_64 https://alpha.de.repo.voidlinux.org/current 2016807 578996
libwavpack-5.3.0_1 configure x86_64 https://alpha.de.repo.voidlinux.org/current 174280 86184
libfluidsynth-2.1.3_1 configure x86_64 https://alpha.de.repo.voidlinux.org/current 448560 216298
I want to know only two things, the packages that are bigger than a MiB. The download size is in column 5, so, I did the following to get in human readable format, filter through grep and pretty print.
~ $ xbps-install -un | numfmt --field=5 --to=si | grep -P '\d+M' | awk '{printf("%30s%7s\n",$1,$5);}' | head -n 5
amdvlk-2020.Q3.2_1 54M
audacious-4.0.5_1 2.1M
audacious-plugins-4.0.5_1 6.2M
openvdb-7.0.0_1 9.2M
alembic-1.7.13_1 3.0M
This works great. I want to make it shorter. I know has awk (mine is gawk) has a inbuilt PCRE, so I can get rid of grep. But when I try this, I get nothing.
~ $ xbps-install -un | numfmt --field=5 --to=si | awk '$5==/\d+M/ {printf("%30s%7s\n",$1,$5);}'
But awk throws me an error saying,
awk: cmd. line:1: warning: regexp escape sequence `\d' is not a known regexp operator
I thought gawk supported PCRE, but apparently it doesn't. So, I replace \d+
with [0..9]+
. I get no error, but no output. Please help fix the error. Is there a way to run a command inside AWK? Something like this
~ $ xbps-install -un | awk '$5>1024 { print $1 `numfmt --to=si $5`; }
Is this even possible? Even in Perl/PHP?
EDIT: I'm sorry I asked the question in a wrong way. My main question was if there is a way to expand shell commands in AWK with AWK variables. For example, in bash shell commands can be expanded as below,
~ $ file `which python`
~ $ file $(which python)
~ $ file (which python) # in fish
Similarly, I want to numfmt
a awk variable, $5
like numfmt --to=iec $5
. So, I was wondering if I can do something like
~ $ xbps-install -un | awk '$5>1024 { print $1 `numfmt --to=si $5`; }
Your awk
just needs to be written as below. And \d
is a PCRE digit pattern which is not/never supported in GNU Awk. Pipe the output of numfmt
to below
awk '$5 ~ /M$/{ printf("%30s%7s\n", $1, $5) }'
which means, match those columns in $5
whose last character ends with an M
which would be the converted SI units in MB
The pattern below is wrong, because the ==
brings in literal string "equality" check in Awk, which you have intermingled with an incorrect PCRE construct.
awk '$5==/\d+M/'
Also the range expressions need to be written as [0-9]
and not [0..9]
.
For the updated question, for which OP wants to use numfmt
inside awk
, for which I don't see a reason as they can very well pipe the output of numfmt
to awk
.
If you want to run the numfmt
command inside awk
, you can use the getline
function in awk
awk '$5 > 1024 { cmd = "numfmt --to=si " $5; print $1, ((cmd | getline res)>0)? res : $5; close(cmd) }'
This approach is not needed as your original cmd | numfmt | awk
cmd | numfmt | awk
cmd | numfmt | awk
approach is very well valid.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.