Why can’t grep find negative numbers?

Suppose you’re looking for instances of -42 in a file foo.txt. The command

    grep -42 foo.txt

won’t work. Instead you’ll get a warning message like the following.

    Usage: grep [OPTION]... PATTERN [FILE]...
    Try 'grep --help' for more information.

Putting single or double quotes around -42 won’t help. The problem is that grep interprets 42 as a command line option, and <codegrep doesn’t have such an option. This is a problem if you’re searching for negative numbers, or any pattern that beings with a dash, such as -able or --version.

The solution is to put -e in front of a regular expression containing a dash. That tells grep that the next token at the command line is a regular expression, not a command line option. So

    grep -e -42 foo.txt

will work.

You can also use -e several times to give grep several regular expressions to search for. For example,

    grep -e cat -e dog foo.txt

will search for “cat” or “dog.”

See the previous post for another example of where grep doesn’t seem to work. By default grep supports a restricted regular expression syntax and may need to be told to use “extended” regular expressions.

7 thoughts on “Why can’t grep find negative numbers?

  1. You can also use a double dash ( — ) to signify the end of command options, after which only positional parameters are accepted:

    grep — -42 foo.txt

  2. Anyway you should precede it with a word boundary marker to exclude “40-42” or similar which does not contain “minus forty two”.

  3. The problem happens because grep thinks that “-42” is an option. Here are three ways to get around that:

    grep -e -42 file.txt # mark as a regex
    grep \\-42 file.txt # escape the dash (once for shell, once for grep itself)
    grep — -42 file.txt # Use ‘–‘ to signal the end of options

  4. You shouldn’t use -e (regex search) when you can use -f (“fast” = fixed string). And yes, as others said, the standard method/syntax/convention of saying “options are finished, now come arguments” is the double dash – – (no space between the “-“).

Comments are closed.