3

How can I match with grep the regex RH[A-ZA-Z], so string includes RH with two characters that both are a letter between A and Z?

I tried this but without success:

 yum list-security --security | awk '{print $1}' | sort | uniq | grep RH[A-ZA-Z]
 Loaded
 RHEA-2014:1307
 RHSA-2014:1326
 RHBA-2014:1388
 RH@A-2014:1389
 RHSA-2014:1392
 RHSA-2014:1389
 RH7A-2014:1392
 RHSAA-2014:1389
 RHMAW-2014:1392

This is what I expected:

 RHEA-2014:1307
 RHSA-2014:1326
 RHBA-2014:1388
 RHSA-2014:1392
 RHSA-2014:1389
10

RH[A-ZA-Z] is a regular expression that includes a single character class that repeats the same set of characters twice. It matches RH followed by any character from A to Z. It places no restrictions on the fourth character, it doesn't even require there to be a fourth character.

Obviously, that doesn't do what you want.

Try this: RH[A-Z][A-Z] or (with extended grep -E or perl grep -P regexps) RH[A-Z]{2}

Also, it's a good idea to put single-quotes (or double-quotes if you need to include a variable or command substitution) around regular expressions to make sure the shell won't try to expand them as globs - e.g. if you had a filename RHAA in the current directory, the shell would expand your argument to RHAA and that's all that your grep would see:

$ grep RH[A-Z][A-Z] yael.txt  | wc -l
7
$ touch RHAA
$ grep RH[A-Z][A-Z] yael.txt  | wc -l
0

equivalent to:

$ grep RHAA yael.txt  | wc -l
0

but it gets worse. If you also have a file called 'RHAB', the grep command line will expand to:

grep RHAA RHAB yael.txt

so grep will search for regexp RHAA in file RHAB as well as stdin and/or the named file(s) you want to search.

Use grep with quotes instead: grep 'RH[A-Z][A-Z]'


Update:

If you want RH followed by only two [A-Z] characters (but no more than two), use this instead:

grep 'RH[A-Z][A-Z][^A-Z]' yael.txt

The third character class [^A-Z] begins with ^, which negates or inverts the class. In other words it matches any character except A to Z.


And you probably want to anchor the match to the beginning of the line, regardless of which version of the regexp you use. You use ^ for that too, but it has a completely different meaning outside of []. It's the beginning-of-line anchor. For example, this:

grep '^RH[A-Z][A-Z][^A-Z]' yael.txt

will only match lines beginning with RH[A-Z][A-Z][^A-Z], and will not match lines with that pattern anywhere else.

  • Your expression also matches the 3-letter suffixes, which the OP doesn't seem to want - don't you need to anchor the back end with a hyphen RH[A-Z][A-Z]- or non-[A-Z] character RH[A-Z][A-Z][^A-Z]? – steeldriver Jul 10 '16 at 11:31
  • @steeldriver - true...i thought about adding it but it's not what the OP asked for "string include RH with two charterers that both can be between A-Z". i'll update my answer anyway. – cas Jul 10 '16 at 12:15
  • Won't it be better to use grep "RH[[:upper:]][[:upper:]][^[:alpha:]]"? – unxnut Jul 10 '16 at 13:40
  • for some kinds of input text, possibly. but it seems a bit unlikely that RedHat Security Advisories will have non-ascii characters in the id. – cas Jul 10 '16 at 13:51
  • What? Why not RH[A-Z]{0,2} or whatever? – cat Jul 10 '16 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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