Home > Mobile >  Ruby Scan method, regex
Ruby Scan method, regex

Time:09-25

Hi Im trying to parse this string with scan method

test = "Disk/File System/[/dev/mapper/rhel-var (/var)]/MB free=14791, Disk/File System/[/dev/mapper/rhel-home (/home)]/MB free=9451, Disk/File System/[/dev/mapper/rhel-opt (/opt)]/percent full=1.0"

I have to capture the path : /dev/mapper/rhel-var (/var) and the number on percent full: 1.0

I have tried with many regex but I can get it to work

testa = test.gsub(',', '')
r = testa.scan(/Disk\/File System\/\[((.*))\]\/percent full=([^[:space:]] )/)
puts r

---Edit---

the string can have multiple ocurrences of of the FS and the percentage:

test = "Disk/File System/[/dev/mapper/rhel-var (/var)]/MB free=14791, Disk/File System/[/dev/mapper/rhel-home (/home)]/MB free=9451, Disk/File System/[/dev/mapper/rhel-opt (/opt)]/percent full=1.0, Disk/File System/[/dev/sda2 (/boot)]/MB total=1974, Disk/File System/[/dev/mapper/rhel-home (/home)]/MB total=10015, Disk/File System/[/dev/mapper/rhel-root (/)]/percent full=61.0, Disk/File System/[/dev/mapper/rhel-var (/var)]/percent full=23.0, Disk/File System/[/dev/mapper/rhel-opt (/opt)]/MB total=452543, Disk/File System/[/dev/mapper/rhel-opt (/opt)]/MB free=426145, Disk/File System/[/dev/mapper/rhel-root (/)]/MB total=10015, Disk/File System/[/dev/mapper/rhel-root (/)]/MB free=3717, Disk/File System/[/dev/mapper/rhel-var (/var)]/MB total=20030, Disk/File System/[/dev/sda2 (/boot)]/percent full=9.0, Disk/File System/[/dev/sda2 (/boot)]/MB free=1699, Disk/File System/[/dev/mapper/rhel-home (/home)]/percent full=1.0, Disk/File System/[devtmpfs (/dev)]/MB total=3851, Disk/File System/[devtmpfs (/dev)]/percent full=0.0, Disk/File System/[devtmpfs (/dev)]/MB free=3851"

help please, thanks

CodePudding user response:

I will write the string as follows to clarify its structure.

test = "Disk/File System/[/dev/mapper/rhel-var (/var)]/MB free=14791,"  
       "Disk/File System/[/dev/mapper/rhel-home (/home)]/MB free=9451,"  
       "Disk/File System/[/dev/mapper/rhel-opt (/opt)]/percent full=1.0,"  
       "Disk/File System/[/dev/sda2 (/boot)]/MB total=1974,"  
       "Disk/File System/[/dev/mapper/rhel-home (/home)]/MB total=10015, "  
       "Disk/File System/[/dev/mapper/rhel-root (/)]/percent full=61.0,"  
       "Disk/File System/[/dev/mapper/rhel-var (/var)]/percent full=23.0, "  
       "Disk/File System/[/dev/mapper/rhel-opt (/opt)]/MB total=452543, "  
       "Disk/File System/[/dev/mapper/rhel-opt (/opt)]/MB free=426145,"  
       "Disk/File System/[/dev/mapper/rhel-root (/)]/MB total=10015,"       
       "Disk/File System/[/dev/mapper/rhel-root (/)]/MB free=3717,"  
       "Disk/File System/[/dev/mapper/rhel-var (/var)]/MB total=20030,"  
       "Disk/File System/[/dev/sda2 (/boot)]/percent full=9.0,"  
       "Disk/File System/[/dev/sda2 (/boot)]/MB free=1699,"  
       "Disk/File System/[/dev/mapper/rhel-home (/home)]/percent full=1.0, "  
       "Disk/File System/[devtmpfs (/dev)]/MB total=3851, "  
       "Disk/File System/[devtmpfs (/dev)]/percent full=0.0, "  
       "Disk/File System/[devtmpfs (/dev)]/MB free=3851"

I assume you want to extract all pairs of paths and "percent full" values, disregarding paths that are not followed by "percent full".

You may write

r = /\bDisk\/File System\/\[([^\]] )\]\/percent full=(\d \.\d)/
test.scan(r)
  #=> [["/dev/mapper/rhel-opt (/opt)", "1.0"],
  #    ["/dev/mapper/rhel-root (/)", "61.0"],
  #    ["/dev/mapper/rhel-var (/var)", "23.0"],
  #    ["/dev/sda2 (/boot)", "9.0"],
  #    ["/dev/mapper/rhel-home (/home)", "1.0"],
  #    ["devtmpfs (/dev)", "0.0"]]

The regular expression can be written in free-spacing mode to make it self-documenting.

r = /
    \b                     # assert a word break
    Disk\/File System\/\[  # match a string
    ([^\]] )               # match 1 or more chars other than ']',
                           #   saved to capture group 1
    \]\/percent[ ]full=    # match a string
    (\d \.\d)              # match one or more digits followed by '.', followed
                           #   by one digit, saved to capture group 2 
    /x                     # invoke free-spacing regex definition mode

Note that in free-spacing mode the space between percent and full would be stripped out before the expression is parsed if it were not protected in some way. Enclosing the space in a character class, as I have done, is one of several ways of doing that.

CodePudding user response:

You can use

/Disk\/File System\/\[([^\]\[]*)\]\/percent full=(\d (?:\.\d )?)/

See the Rubular demo (regex101 demo). Details:

  • Disk\/File System\/\[ - a Disk/File System/[ string
  • ([^\]\[]*) - Group 1: any zero or more chars other than [ and ], as many as possible
  • \]\/percent full= - a ]/percent full= text
  • (\d (?:\.\d )?) - Group 2: one or more digits and then an optional sequence of a . and one or more digits.

In Ruby:

test = "Disk/File System/[/dev/mapper/rhel-var (/var)]/MB free=14791, Disk/File System/[/dev/mapper/rhel-home (/home)]/MB free=9451, Disk/File System/[/dev/mapper/rhel-opt (/opt)]/percent full=1.0, Disk/File System/[/dev/sda2 (/boot)]/MB total=1974, Disk/File System/[/dev/mapper/rhel-home (/home)]/MB total=10015, Disk/File System/[/dev/mapper/rhel-root (/)]/percent full=61.0, Disk/File System/[/dev/mapper/rhel-var (/var)]/percent full=23.0, Disk/File System/[/dev/mapper/rhel-opt (/opt)]/MB total=452543, Disk/File System/[/dev/mapper/rhel-opt (/opt)]/MB free=426145, Disk/File System/[/dev/mapper/rhel-root (/)]/MB total=10015, Disk/File System/[/dev/mapper/rhel-root (/)]/MB free=3717, Disk/File System/[/dev/mapper/rhel-var (/var)]/MB total=20030, Disk/File System/[/dev/sda2 (/boot)]/percent full=9.0, Disk/File System/[/dev/sda2 (/boot)]/MB free=1699, Disk/File System/[/dev/mapper/rhel-home (/home)]/percent full=1.0, Disk/File System/[devtmpfs (/dev)]/MB total=3851, Disk/File System/[devtmpfs (/dev)]/percent full=0.0, Disk/File System/[devtmpfs (/dev)]/MB free=3851"
rx = /Disk\/File System\/\[([^\]\[]*)\]\/percent full=(\d (?:\.\d )?)/
puts test.scan(rx)

Output:

[
   ["/dev/mapper/rhel-opt (/opt)", "1.0"],
   ["/dev/mapper/rhel-root (/)", "61.0"],
   ["/dev/mapper/rhel-var (/var)", "23.0"],
   ["/dev/sda2 (/boot)", "9.0"],
   ["/dev/mapper/rhel-home (/home)", "1.0"],
   ["devtmpfs (/dev)", "0.0"]
]
  • Related