2

I have this command right here:

grep -B10 -A10 '14:14:50 {"channels":["/alerts/6979/new"],"data":"New alerts for unit 6979"}' mygateway.log

Rather than searching for 14:14:50 I would like the 50 to be replaced with any number. So I was thinking to use the "." to represent any character in a regular expression. However, in programming languages you usually signify a regex with something like \abc.xyz\ where "." could be any character and any number of characters. But when I use "." in that grep string above it doesn't give me anything back.

  • why not [0-9][0-9]? Or [0-9]\? instead of 50 – fclad Sep 15 '13 at 19:36
4

The issue here is that . is used to signify any single character. So the . would match the 5 in 50 but, with nothing to match the 0, the rest of the line fails to match. In any case, since you know that what you're looking for is any number, you should be more specific with your regex. Match any number with:

[0-9]\+

If you know that this number can have an optional fractional part (after a decimal point), you can use the following:

[0-9]\+\(\.[0-9]\+\)?

The backslash before the + and the parens should be omitted if you're using grep's -P (PCRE) option.

If you do plan to use the -P option, you should know it's not in the POSIX standard and may not be available on all platforms.

1

You could also use the -P flag to enable Perl compatible regular expressions and use \d:

grep -P -B10 -A10 '14:14:\d+ {"channels":["/alerts/6979/new"],"data":"New alerts for unit 6979"}' mygateway.log

You could also really simplify it by making it less restrictive (the details depend on your input data of course but this should work):

grep -P -B10 -A10 '14:14:\d+.*channels.*alerts/6979/new.*data.*New' mygateway.log

I am assuming that if the line matches both /alerts/6979/new/ and New, the rest is unchanging.

  • Perl's \d class is notorious for behaving unexpectedly in non-ASCII environments. [0-9] is usually what is meant. I'm sure you know this already; this is an FYI for other readers. – Joseph R. Sep 15 '13 at 19:44
  • Read here under the heading "Digits". – Joseph R. Sep 15 '13 at 19:47
  • @JosephR. That might apply to perl, but probably not to the PCREs (which are not perl regular expressions) as used in GNU grep -P. Even echo '\u09EA' | LC_ALL=bn_BD.UTF-8 grep -P '(*UCP)\d' doesn't seem to match, though that may be down to GNU libc or to my actual bengali locale definition – Stéphane Chazelas Sep 15 '13 at 21:50
  • @StephaneChazelas Thanks for the clarification and the interesting example. Can you please explain the (*UCP) part, though? – Joseph R. Sep 15 '13 at 21:57
  • 1
    @JosephR. Yes, and as I said, you can turn PCRE_UCP by adding (*UCP) in the regexp, but even then I don't see it matching non-ASCII digits on my system. – Stéphane Chazelas Sep 16 '13 at 9:28

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.