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.

1
  • why not [0-9][0-9]? Or [0-9]\? instead of 50
    – fclad
    Commented Sep 15, 2013 at 19:36

2 Answers 2

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.

16
  • 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.
    Commented Sep 15, 2013 at 19:44
  • Read here under the heading "Digits".
    – Joseph R.
    Commented Sep 15, 2013 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 Commented Sep 15, 2013 at 21:50
  • @StephaneChazelas Thanks for the clarification and the interesting example. Can you please explain the (*UCP) part, though?
    – Joseph R.
    Commented Sep 15, 2013 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. Commented Sep 16, 2013 at 9:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .