bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Exclamation mark when using character classes


From: Kerin Millar
Subject: Re: Exclamation mark when using character classes
Date: Sat, 21 Aug 2021 02:48:04 +0100

On Fri, 20 Aug 2021 23:33:38 +0000
hancooper <hancooper@protonmail.com> wrote:

> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
> On Friday, August 20, 2021 8:00 PM, Kerin Millar <kfm@plushkava.net> wrote:
> 
> > On Fri, 20 Aug 2021 19:28:25 +0000
> > hancooper via Bug reports for the GNU Bourne Again SHell bug-bash@gnu.org 
> > wrote:
> >
> > > I am using EPOCHREALTIME and then computing the corresponding human 
> > > readable form, that can handle
> > > changes in locale
> > > now=$EPOCHREALTIME
> > > printf -v second '%(%S)T.%s' "${now%[^[:digit:]]}" "${now#[^[:digit:]]}"
> > > printf -v minute '%(%M)T' "${now%[^[:digit:]]}"
> > > printf -v hour '%(%H)T' "${now%[^[:digit:]]}"Incidentally, [![:digit:]] 
> > > does not work there, you need to use the POSIX-specified caret (^) 
> > > instead of an
> > > exclamation mark when using character classes. I'm not sure if this is 
> > > intentional or a bug in bash; man
> > > page doesn't seem to mention it.
> >
> > "If an open bracket introduces a bracket expression as in XBD RE Bracket 
> > Expression, [...] the <exclamation-mark> character ( '!' ) shall replace 
> > the <circumflex> character ( '^' ) in its role in a non-matching list in 
> > the regular expression notation."
> >
> > So says POSIX on the matter of pattern matching notation. In other words, 
> > only the exclamation-mark is POSIX-specified, although bash happens to 
> > tolerate the use of a circumflex, in which case it should behave in the 
> > exact same way. Are you able to show a concrete example of one behaving 
> > differently from the other?
> 
> 
> I could do with some help separating the integer and the fractional part from 
> a floating point number,
> particularly for the situation where the number starts with a period.
> 
>     t="13.357713"
> 
>     # integer part of time interval
>     ts="${t%%[![:digit:]]+([:digit:])}"  # remove longest match from back
>                                          # 13.877597, remove .877597
> 
>     # fractional part of time interval
>     fr="${t##*([:digit:])[![:digit:]]}"  # remove longest match from front
>                                          # 13.877597, remove 13.

"[:digit:]" is missing the additional pair of square brackets that would have 
it be treated as a character class name. Assuming that the extglob option has 
been enabled, try this.

ts=${t%%[![:digit:]]+([[:digit:]])}
fr=${t##*([[:digit:]])[![:digit:]]}

If it's only the value of EPOCHREALTIME that you are concerned with, your 
approach could perhaps be simplified on the basis that it has a well-defined 
format of %u.%06u, where "." may also be some other radix character.

t=$EPOCHREALTIME
ts=${t:0:-7}
fr=${t:(-6)}

-- 
Kerin Millar



reply via email to

[Prev in Thread] Current Thread [Next in Thread]