[SLL] Scripting Question

Ana christiana at hipointcoffee.com
Thu Oct 4 14:02:22 PDT 2007


On Wed, Oct 03, 2007 at 10:43:33PM -0700, Robert Woodcock wrote:
> On Wed, Oct 03, 2007 at 03:30:48PM -0700, Eric wrote:
> > I am biting the bullet and trying to learn more about shell and perl 
> > scripting.  I have two unrelated questions.
> > 
> > 1.  Using perl regular expression, how could I match a string followed 
> > by a period and a digit? The string doesn't have to include the period 
> > and digit though. For example, I'd want to match something like this:
> > 
> > string
> > string.2
> > 
> > but not:
> > 
> > strings
> > string9
> > string.
> > strings.2
> > 
> > So far I've come up with
> > /^string\.?[0-9]?/
> 
> $ cat /tmp/testfile
> string
> string.2
> strings
> string9
> string.
> strings.2
> $ perl -ne 'print if /string($|\.\d)/;' /tmp/testfile
> string
> string.2


This may leave out an important test case. add: "string.2 string9"  that
to the list and this example will include it in the output.  whether
that's wanted or not is not entirely clear.  Also, in the real problem,
does each line really begin with exactly the same data: /^string/?  That
would be a very unusual case.

I added few test cases added (one added test case is a blank line, no
spaces, tabs, etc.)
-----------------------------------------------------------
$ cat /tmp/testfile
string
string.2
strings
not string
string9
34 string 89
34 string 89.0

string.
not string.2
string.2 string9
oijadfoijao.3
823 oaf 9823 .5
823 oaf 9823
823 oaf 9823 string.2
.2
$ perl -wne 'print if /^string\.?[0-9]?/;' /tmp/testfile
string
string.2
strings
string9
string.
string.2 string9
$ perl -ne 'print if /string($|\.\d)/;' /tmp/testfile
string
string.2
not string
not string.2
string.2 string9
823 oaf 9823 string.2
$ perl -ne 'print if /^string($|\.\d)/;' /tmp/testfile
string
string.2
string.2 string9
$ perl -wne 'print if /string(\.\d)?$/;' /tmp/testfile
string
string.2
not string
not string.2
823 oaf 9823 string.2
$ perl -wne 'print if /^string(\.\d)?$/;' /tmp/testfile
string
string.2
$
-----------------------------------------------------------


or, if you don't care if "string" is precisely the last exact string
just before the end...  but only wish to make sure that the line ends
either with <a period and a single single digit> or <any character (at
least one) except a period or a digit>...
-----------------------------------------------------------
$ perl -wne 'print if /\.\d$/ || (/./ && ! /[.0-9]$/) ;' /tmp/testfile
string
string.2
strings
not string
34 string 89.0
not string.2
oijadfoijao.3
823 oaf 9823 .5
823 oaf 9823 string.2
.2
$
-----------------------------------------------------------

notice in the last one, three regexs are used.  This is one of the most
important things I've learned about perl and regexs in general:  It's
very often easier to accomplish what you want with multiple, small,
simple regexs than with a single, larger, complex regex.


One last test.  Say you want both the period and single digit or
neither, right at the end;  And you want the exact string "string" to
appear somewhere within the line but not necessarily at the end before
the period and digit.
-----------------------------------------------------------
$ perl -wne 'print if /string.*?\.\d$/ || (/string/ && ! /[.0-9]$/) ;' /tmp/testfile
string
string.2
strings
not string
34 string 89.0
not string.2
823 oaf 9823 string.2
$
-----------------------------------------------------------


The O'Reilly regex book is an excellent place to start.  It takes a
couple days to read and digest most of the important stuff, and it's
worth the time.

- Ana



More information about the linux-list mailing list