diff --git a/docs/man/man1/ansible.1 b/docs/man/man1/ansible.1
index e12f8730b8a..e3e0bd2a610 100644
--- a/docs/man/man1/ansible.1
+++ b/docs/man/man1/ansible.1
@@ -2,12 +2,21 @@
.\" Title: ansible
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.75.2
-.\" Date: 11/03/2012
+.\" Date: 12/04/2012
.\" Manual: System administration commands
.\" Source: Ansible 0.9
.\" Language: English
.\"
-.TH "ANSIBLE" "1" "11/03/2012" "Ansible 0\&.9" "System administration commands"
+.TH "ANSIBLE" "1" "12/04/2012" "Ansible 0\&.9" "System administration commands"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -25,7 +34,7 @@ ansible \- run a command somewhere else
ansible [\-f forks] [\-m module_name] [\-a args]
.SH "DESCRIPTION"
.sp
-\fBAnsible\fR is an extra\-simple tool/framework/API for doing \'remote things\' over SSH\&.
+\fBAnsible\fR is an extra\-simple tool/framework/API for doing \*(Aqremote things\*(Aq over SSH\&.
.SH "ARGUMENTS"
.PP
\fBhost\-pattern\fR
@@ -73,7 +82,7 @@ to load modules from\&. The default is
\fI/usr/share/ansible\fR\&.
.RE
.PP
-\fB\-a\fR \'\fIARGUMENTS\fR\', \fB\-\-args=\fR\'\fIARGUMENTS\fR\'
+\fB\-a\fR \*(Aq\fIARGUMENTS\fR\*(Aq, \fB\-\-args=\fR\*(Aq\fIARGUMENTS\fR\*(Aq
.RS 4
The
\fIARGUMENTS\fR
@@ -156,6 +165,11 @@ is mostly useful for crontab or kickstarts\&.
.RS 4
Further limits the selected host/group patterns\&.
.RE
+.PP
+\fB\-l\fR \fI~REGEX\fR, \fB\-\-limit=\fR\fI~REGEX\fR
+.RS 4
+Further limits hosts with a regex pattern\&.
+.RE
.SH "INVENTORY"
.sp
Ansible stores the hosts it can potentially operate on in an inventory file\&. The syntax is one host per line\&. Groups headers are allowed and are included on their own line, enclosed in square brackets that start the line\&.
diff --git a/docs/man/man1/ansible.1.asciidoc.in b/docs/man/man1/ansible.1.asciidoc.in
index 22c11aa95ab..f55c7ff41ea 100644
--- a/docs/man/man1/ansible.1.asciidoc.in
+++ b/docs/man/man1/ansible.1.asciidoc.in
@@ -117,6 +117,10 @@ and 'local'. 'local' is mostly useful for crontab or kickstarts.
Further limits the selected host/group patterns.
+*-l* '\~REGEX', *--limit=*'~REGEX'::
+
+Further limits hosts with a regex pattern.
+
INVENTORY
---------
diff --git a/lib/ansible/inventory/__init__.py b/lib/ansible/inventory/__init__.py
index 2316104b63b..e13bb2d346b 100644
--- a/lib/ansible/inventory/__init__.py
+++ b/lib/ansible/inventory/__init__.py
@@ -19,6 +19,7 @@
import fnmatch
import os
+import re
import subprocess
import ansible.constants as C
@@ -92,7 +93,10 @@ class Inventory(object):
raise errors.AnsibleError("YAML inventory support is deprecated in 0.6 and removed in 0.7, see the migration script in examples/scripts in the git checkout")
def _match(self, str, pattern_str):
- return fnmatch.fnmatch(str, pattern_str)
+ if pattern_str.startswith('~'):
+ return re.search(pattern_str[1:], str)
+ else:
+ return fnmatch.fnmatch(str, pattern_str)
def get_hosts(self, pattern="all"):
"""
@@ -157,7 +161,7 @@ class Inventory(object):
a tuple of (start, stop) or None
"""
- if not "[" in pattern:
+ if not "[" in pattern or pattern.startswith('~'):
return (pattern, None)
(first, rest) = pattern.split("[")
rest = rest.replace("]","")
diff --git a/test/TestInventory.py b/test/TestInventory.py
index 1f053afd3b6..a089aa1a749 100644
--- a/test/TestInventory.py
+++ b/test/TestInventory.py
@@ -158,6 +158,14 @@ class TestInventory(unittest.TestCase):
print "EXPECTED=%s" % sorted(expected_hosts)
assert sorted(hosts) == sorted(expected_hosts)
+ def test_regex_exclude(self):
+ inventory = self.complex_inventory()
+ hosts = inventory.list_hosts("~rtp_[ac]")
+ expected_hosts = ['rtp_a', 'rtp_c']
+ print "HOSTS=%s" % sorted(hosts)
+ print "EXPECTED=%s" % sorted(expected_hosts)
+ assert sorted(hosts) == sorted(expected_hosts)
+
def test_complex_enumeration(self):