Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Converting bash script to zsh for converting bytes to 'readable'
- X-seq: zsh-users 23625
- From: Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx>
- To: TJ Luoma <luomat@xxxxxxxxx>
- Subject: Re: Converting bash script to zsh for converting bytes to 'readable'
- Date: Wed, 12 Sep 2018 23:04:45 +0000
- Cc: Zsh-Users List <zsh-users@xxxxxxx>
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= daniel.shahaf.name; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; bh=qcm2RXQEImjNbcG3pQmhcKVf1gFVn ZkUU+f5wZ9ckv0=; b=eCxIAXdSZ+3cn3SgsYWLLiC3772o77h2brbtm0vC5O07n uu2925U+UaPZJL2fqTIdEWuE3RhRoqRV/H9aov9S62n5xyrY9LyD50rX4zxu6HhW zFDtK4CbLS9PMAw7jUwsGCrLSye6B3Zg0LYkDSN+xxLhThslYP2wHtQbEizYnCa5 Lk63SnZ24o+pcqk0b7blU//6I6hsSe72a5Sqzi+siqxcU7fRXYUeU+kELqMWqRmP +lG3VAtqTJ0ab9h2wJWgCfcjXtSNn5AbtJ3iK14dqf9FUlfLrmgSHvP++k2ilOnb TMC7YPdAdsErH8d5X/e2siTJ4a2+rAIxm23rPBeJQ==
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; bh=qcm2RXQEImjNbcG3pQmhcKVf1gFVn ZkUU+f5wZ9ckv0=; b=GTzf2V61WHQuZmL/mSXCG6YZxPvbYKQbU6Ey875ljl/k+ KfdCI5h2LpvAasYJAIs7sJKaXf6UbuQiljAB5lEdOfmmBv4DTviNqHcuVHY8IDlJ hb9oa5fkRgqL6LHgkyk860Kuq/KKrhRS8cw4fiq3GOwyaOupe/kfev1b17OvezuZ Bc8uV/TPpzaLyAxjzqUq6BG5sHb4ZUGF+gn5eAvVV5anTF9k4WHdE5EPehqWiIcG x5V3eRUmk10VGvddbO4dXwV1kG79Yu3ugNpTMl2F3QyZxpf/LCOv4/X/SniiXYaH 5hKvNr4PuIOrWPux74enhg3vNFtOgFTNCkM1VIfkw==
- In-reply-to: <CADjGqHtKCEc-cwrQXOtjVSrYE6U+tpP5aYWrfd9prrVmvOKrtg@mail.gmail.com>
- List-help: <mailto:zsh-users-help@zsh.org>
- List-id: Zsh Users List <zsh-users.zsh.org>
- List-post: <mailto:zsh-users@zsh.org>
- List-unsubscribe: <mailto:zsh-users-unsubscribe@zsh.org>
- Mailing-list: contact zsh-users-help@xxxxxxx; run by ezmlm
- References: <CADjGqHtKCEc-cwrQXOtjVSrYE6U+tpP5aYWrfd9prrVmvOKrtg@mail.gmail.com>
TJ Luoma wrote on Wed, Sep 12, 2018 at 18:02:26 -0400:
> I don't really understand what the 'while' loop is doing, and I don't know
> if zsh has 'floats' (which I assume is 'floating point'?).
>
Yes, zsh has floating point variables, for example, 'typeset -F foo'.
The 'while' loop divides the number by 1000 in each iteration to figure
out the magnitude. It's like counting digits to figure out the exponent
to use for scientific notation (1024 == 1.024e+3).
> METRIC=('KB' 'MB' 'GB' 'TB' 'XB' 'PB')
This should read KB MB GB TB PB EB ZB YB.
> Does that look correct to you? Did I miss anything? It appears to work in
> my (limited, so far) testing, but I'm worried that I'm overlooking
> something.
>
It may be correct, but it's not idiomatic. For one, it's not idiomatic
to treat floating point numbers as strings. I'm not sure what scale=2
to bc(1) does but it's probably possible to do that in native zsh too.
Likewise for the tr(1) though that's not as crucial.
For instance, the loop could have been written like this:
.
while (( UNITS <= MBYTES )); do
.
(but read on)
> Alternatively: is there another / easier way of doing this that I should
> use instead? Some 'zmodload' or something?
I think this does what you want?
1 zmodload zsh/mathfunc
2 f() {
3 setopt localoptions ksharrays
4 integer i=$(( log2( $1 )/10 ))
5 local -a SI=( '' 'Ki' 'Mi' 'Gi' )
6 printf '%5.2g %s\n' "$(( ($1)*1.0 / (1<<(10*i)) ))" "${SI[i]}B"
7 }
Explanation (by line number)
1: Enables the 'log2' math function (requires zsh 5.6)
3: I'd like to use zero-based array indexes, purely for convenience.
(I could've changed [i] to [i+1] on line 7 instead.)
4: Take the base-2 logarithm of the input and divide it by 10 to get the
order of magnitude. Using an integer variable implicitly truncates the
input. (You may prefer rounding to truncating, in order for 1023 to map
to KiB rather than to plain B.)
6: Divide the input by the largest power of 1024 smaller than it, printf
that, and append the appropriate SI prefix from the lookup array.
Multiply by 1.0 to ensure at least one of the arguments to '/' is a
float, in order for the division expression to evaluate to a floating
point quantity. (Integer division results in an integer: compare
$((5/2)) and $((5.0/2)).)
Cheers,
Daniel
Messages sorted by:
Reverse Date,
Date,
Thread,
Author