Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Thread: Regex pattern matching

  1. #1
    Join Date
    Sep 2012
    Beans
    94
    Distro
    Ubuntu 12.04 Precise Pangolin

    Regex pattern matching

    Hi All,

    I tried to use regex to do a pattern matching for CPU % usage. i only need the value, 0.0.

    The command i use:
    Code:
    top -bn1 | grep "Cpu(s)" | grep ".\.." | grep ".\..%us"
    The result:
    Code:
    Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
    After some time, i managed to get the right regex for the pattern matching but its not work in my server.
    The error prompt out:
    Code:
    top -bn1 | grep \d.\d(?=%us)
    -bash: syntax error near unexpected token `('
    Any way i can solve this?
    Thanks

  2. #2
    Join Date
    Jun 2011
    Location
    United Kingdom
    Beans
    Hidden!
    Distro
    Lubuntu Development Release

    Re: Regex pattern matching

    For your error, that's because your shell (bash) attempts to parse the expression you give to grep, and fails. To avoid that, use quotes:

    Code:
    top -bn1 | grep '\d.\d(?=%us)'
    However, that doesn't seem to work, at least not on my system, and I don't know enough about grep's pattern matching to fix it. Instead, I used a combination of grep (to get the right line), awk (to get the right column), and sed (trim excess rubbish):

    Code:
    $ top -bn1 | grep 'Cpu(s)' | awk '{print $2}' | sed 's/%us,//g'
    7.4

  3. #3
    Join Date
    Dec 2007
    Beans
    12,521

    Re: Regex pattern matching

    In this specific instance
    Code:
    top -bn1 | awk 'NR==3 { print $2}'
    seems to do as well.

  4. #4
    Join Date
    Apr 2012
    Beans
    7,256

    Re: Regex pattern matching

    You are trying to use a perl-style regular expression - grep supports that to some extent, but you need to add the -P switch

    Code:
    $ top -bn1 | grep -P '\d.\d(?=%us)'
    Cpu(s):  7.5%us,  5.0%sy,  0.0%ni, 87.2%id,  0.2%wa,  0.0%hi,  0.0%si,  0.0%st
    If you want just the matching number, add -o

    Code:
    $ top -bn1 | grep -oP '\d.\d(?=%us)'
    7.5
    Note that '\d.\d' will match 2 digits separated by ANY single character - if you want to match just the decimal point, you should escape the period, either '\d\.\d' or '\d[.]\d'
    Last edited by steeldriver; November 17th, 2013 at 02:24 PM.

  5. #5
    Join Date
    Sep 2012
    Beans
    94
    Distro
    Ubuntu 12.04 Precise Pangolin

    Re: Regex pattern matching

    Hi,

    Thanks for the response.
    It works.

    I will find more into 'awk' , 'sed' . its usefull.

  6. #6
    Join Date
    Sep 2012
    Beans
    94
    Distro
    Ubuntu 12.04 Precise Pangolin

    Re: Regex pattern matching

    Hi steeldriver,

    Thanks for your explanation.
    I dont know that regex has different style. Thanks again.

  7. #7
    Join Date
    Dec 2007
    Beans
    12,521

    Re: Regex pattern matching

    Quote Originally Posted by steeldriver View Post
    ...
    If you want just the matching number, add -o

    Code:
    top -bn1 | grep -oP  '\d.\d(?=%us)'
    ...
    That code doesn't work for me but this does:
    Code:
    top -bn1 | grep -oP '\d\.\d +(?=us)'
    I tried both on a regular desktop Xubuntu.

    When I checked man pcre, I found this:
    Lookahead assertions

    Lookahead assertions start with `(?=` for positive assertions and `(?!` for
    negative assertions. For example,

    `\w+(?)`

    matches a word followed by a semicolon, but does not include the semi‐
    colon in the match, ...
    This is my grep:
    Code:
    [12:56 PM] ~ $ grep --version
    grep (GNU grep) 2.14
    Copyright (C) 2012 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    
    Written by Mike Haertel and others, see <http://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.

  8. #8
    Join Date
    Apr 2012
    Beans
    7,256

    Re: Regex pattern matching

    @vasa1 your expression matches a different pattern (digit-period-digit followed by one or more spaces) - is your 'top' output different i.e. '7.5 %us' instead of '7.5%us'?

    FWIW for matching a floating point number in general I'd suggest something like

    Code:
    grep -oP '[\d.]+(?=%us)'
    which will match a wider range of possible field widths and precisions i.e. 7%us, 7.5%us, 17%us, 27.5%us etc. (note that the period is treated as literal when inside a [ ] character set, so no need to escape it). If you need to allow for optional trailing whitespace beween the number and the % sign, you could add \s* i.e.

    Code:
    grep -oP '[\d.]+\s*(?=%us)'
    or maybe more perlish

    Code:
    grep -oP '[\d.]+\s+?(?=%us)'
    Last edited by steeldriver; November 18th, 2013 at 01:25 PM.

  9. #9
    Join Date
    Dec 2007
    Beans
    12,521

    Re: Regex pattern matching

    This is what I get when I run top -bn1

    Code:
    [06:06 PM] ~ $ top -bn1
    top - 18:06:09 up  2:27,  2 users,  load average: 0.04, 0.04, 0.05
    Tasks: 133 total,   1 running, 132 sleeping,   0 stopped,   0 zombie
    %Cpu(s):  2.7 us,  0.6 sy,  0.0 ni, 95.5 id,  1.2 wa,  0.0 hi,  0.0 si,  0.0 st
    KiB Mem:   4010624 total,  1106888 used,  2903736 free,    46644 buffers
    KiB Swap:  6159668 total,        0 used,  6159668 free,   660436 cached
    So our top outputs do differ. Any idea why? My top is whatever came with the system.
    Last edited by vasa1; November 18th, 2013 at 01:40 PM.

  10. #10
    Join Date
    Apr 2012
    Beans
    7,256

    Re: Regex pattern matching

    I don't know - top has *lots* of configuration options (plus optional global / personal rc files)... or it could just be the top version? mine is

    Code:
    $ top --version
        top: procps version 3.2.8

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •