Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I wanted to do some simple regex so i am trying to get the 16. I tried grep but i dont see how to write \1 or $1 to only output the capture data and i tried sed but i think i did it wrong due to escaping i am not familiar with. Anyways my regex is this

(\d+)\%\s*/$

The string is

# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/xvda             15997904   2404540  12943248  16% /
tmpfs                   252456         0    252456   0% /lib/init/rw
tmpfs                   252456        36    252420   1% /dev/shm

and on this site the output is exactly what i want (move your mouse over to see group matches) http://regexr.com?2sd12

share|improve this question
add comment

3 Answers 3

awk is very well suited to this task:

df | awk 'NR > 1 {print $5, $6;}'

says skip the first line NR > 1 and then on all other lines print the 5th and 6th whitespace separated fields. It yields:

65% /
1% /dev
1% /dev/shm

added in response to comment:

The demo site didn't match your description, sorry. Although there are simpler ways to do this, here is the same chain with tr added so you have one more tool in your box:

df | awk 'NR > 1 {print $5;}' | tr -d '%'

and if you only wanted it for (e.g.) /dev/shm then:

df | awk '/\/dev\/shm$/ {print $5;}' | tr -d '%'

or root:

df | awk '/\/$/ {print $5;}' | tr -d '%'
share|improve this answer
    
I'm trying to get only the value and not the % sign so i can assign the int to a bash variable. –  acidzombie24 Oct 20 '10 at 14:11
    
The first line is reported anyway in your version, it is better df | awk 'NR > 1 { print $5, $6 }' –  enzotib Oct 20 '10 at 14:44
    
correct you are, enzotib; fixed; thanks. –  msw Oct 20 '10 at 14:56
add comment

By default, grep) prints the whole line matching a regexp, but you can tell it to print just the matching string with option --only-matching:

df -h | egrep --only-matching '[[:digit:]]+%' | tr -d '%'

Note that:

  1. The grep/egrep regexp syntax is a bit different from the PERL-style regexp syntax that you posted. In addition, there are differences between the regexp syntax supported by grep (called "POSIX basic regexp") and the one used in egrep (extended regexp).

  2. There's no way to tell egrep to output a certain subexpression of the match: the whole match will be printed, including the % sign. But you can strip it out with tr.

share|improve this answer
    
weird syntax, why cant i capture with multiple groups? maybe i should learn python or perl and do it from there :x –  acidzombie24 Oct 20 '10 at 16:47
    
Just for fuss: you can have multiple capture groups in an egrep regex, there is just no option to select which one to print; you always get the full match. –  Riccardo Murri Oct 20 '10 at 17:35
    
grep -P can use Perl-regexp syntax (but it's experimental, so probably doesn't work in all cases) –  JanC Oct 20 '10 at 18:18
add comment

Just for fun, you can use Python to retrieve the disk usage.

The following code snippet will display the value at the first occurrence of the pattern (in your case 16):

import subprocess
import re
print re.search('(\d+)% /', subprocess.Popen(["df"], stdout=subprocess.PIPE).communicate()[0]).group(1)

If you'd like to retrieve the values from each line, a little longer code would do the trick:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import subprocess
import re

p = subprocess.Popen(["df"], stdout=subprocess.PIPE)
for line in p.stdout:
    usage = re.search('(\d+)% /', line.rstrip())
    if usage != None:
        print usage.group(1)

Basically it works the same way, just it reads the output line-by-line in contrast to the Popen.communicate() call that retrieves the whole output in one go.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.