Hichigaya Hachiman Hichigaya Hachiman - 9 days ago 5
Bash Question

Finding number range with grep

I have a database in this format:

username:something:UID:something:name:home_folder


Now I want to see which users have a UID ranging from 1000-5000. This is what what I tried to do:

ypcat passwd | grep '^.*:.*:[1-5][0-9]\{2\}:'


My thinking is this: I go to the third column and find numbers that start with a number from 1-5, the next number can be any number - range
[0-9]
and that range repeats itself 2 more times making it a 4 digit number. In other words it would be something like
[1-5][0-9][0-9][0-9]
.

My output, however, lists even UID's that are greater than 5000. What am I doing wrong?

Also, I realize the code I wrote could potentially lists numbers up to 5999. How can I make the numbers 1000-5000?

EDIT: I'm intentionally not using
awk
since I want to understand what I'm doing wrong with
grep
.

Answer

There are several problems with your regex:

  • As Sundeep pointed out in a comment, ^.*:.*: will match two or more columns, because the .* parts can match field delimiters (":") as well as field contents. To fix this, use ^[^:]*:[^:]*:
  • [0-9]\{2\} will match exactly two digits, not three
  • As you realized, it matches numbers starting with "5" followed by digits other than "0"

As a result of these problems, the pattern ^.*:.*:[1-5][0-9]\{2\}: will match any record with a UID or GID in the range 100-599.

To do it correctly with grep, use grep -E '^[^:]*:[^:]*:([1-4][0-9]{3}|5000):' (again, see Sundeep's comments).

Comments