One of the toughest things to learn about regular expressions is just what they do match. The problem is that a regular expression tends to find the longest possible match - which can be more than you want.
showmatch | Here's a simple script called showmatch that is
useful for testing regular expressions, when writing
sed scripts, etc. Given a regular expression and a filename, it
finds lines in the file matching that expression, just like grep, but
it uses a row of carets (^^^^ ) to highlight the portion of the line
that was actually matched. |
---|
#! /bin/sh # showmatch - mark string that matches pattern pattern=$1; shift nawk 'match($0,pattern) > 0 { s = substr($0,1,RSTART-1) m = substr($0,1,RLENGTH) gsub (/[^\b- ]/, " ", s) gsub (/./, "^", m) printf "%s\n%s%s\n", $0, s, m }' pattern="$pattern" $*
For example:
%showmatch 'CD-...' mbox
and CD-ROM publishing. We have recognized ^^^^^^ that documentation will be shipped on CD-ROM; however, ^^^^^^
xgrep | xgrep is a related script that simply retrieves only the matched text.
This allows you to extract patterned data from a file.
For example, you could extract only the numbers from a table
containing both text and numbers.
It's also great for counting the number of occurrences of some pattern
in your file, as shown below.
Just be sure that your expression only matches what you want.
If you aren't sure, leave off the wc command and glance at the
output.
For example, the regular expression [0-9]* will match numbers
like 3.2 twice: once for the 3 and again for the
2 !
You want to include a dot (. ) and/or comma (, ),
depending on how your numbers are written.
For example: [0-9][.0-9]* matches a leading digit, possibly
followed by more dots and digits. |
---|
NOTE: Remember that an expression like
[0-9]*
will match zero numbers (because*
means "zero or more of the preceding character"). That expression can make xgrep run for a very long time! The following expression, which matches one or more digits, is probably what you want instead:xgrep "[0-9][0-9]*"
files
| wc -l
The xgrep shell script runs the sed commands below,
replacing $re
with the regular expression from the command line
and $x
with a CTRL-b character (which is used as a delimiter).
We've shown the sed commands numbered, like 5>
;
these are only for reference and aren't part of the script:
1>
\$x$re$x!d2>
s//$x&$x/g3>
s/[^$x]*$x//4>
s/$x[^$x]*$x/\/g
5>
s/$x.*//
Command 1 deletes all input lines that don't contain a match. On the remaining lines (which do match), command 2 surrounds the matching text with CTRL-b delimiter characters. Command 3 removes all characters (including the first delimiter) before the first match on a line. When there's more than one match on a line, command 4 breaks the multiple matches onto separate lines. Command 5 removes the last delimiter, and any text after it, from every output line.
Greg Ubben revised showmatch and wrote xgrep.
-
,