3

I have a grep that works for some of the dates but having trouble getting my brain to make it fully functional.

grep 19[6-9][5-6]$ filename

it catches a few correctly but I'm looking to grab all years between 1965-1996.

Here is the current solution but looking for a one line really, but here's what I've gotten so far:

grep 196[5-9]$ filename
grep 197[0-9]$ filename
grep 198[0-9]$ filename
grep 199[0-6]$ filename

Looking for better and shorter if possible?

13

Date ranges & regex aren't really that good a match. If I interpret the $ in your grep correctly the date is the last field on a line.

Try this:

awk '$NF >= 1965 && $NF <= 1996' filename

If you must use grep it becomes more convoluted:

grep -E '196[5-9]|19[78][0-9]|199[0-6]$' filename
3
  • Awesome! I wasn't sure how to condense what I had down to one line. Thanks mate! Oct 15 '14 at 20:23
  • 1
    This. The awk solution is the right answer. Don't use grep to find ranges of numbers, it's way too prone to error and difficult to read and modify later. Oct 15 '14 at 20:26
  • I have only been shown grep, I'm hoping awk will show up soon as awk seems to be the way to go! Oct 15 '14 at 21:12
2

You should note that egrep allows the 19 to be factored out, like such:

grep -E '19(6[5-9]|[78][0-9]|9[0-6])$' filename

which might be considered clearer.

1

You could also use seq which I find much more readable:

grep -E "$(seq -s "|" 1965 1996)" filename

-s, --separator=STRING

1
  • Just be careful about the size of the resulting command (and the size of the resulting RE)
    – roaima
    Apr 26 at 14:49
0
$ (for i in {1900..2000}; do echo $i; done) | egrep '(196[5..9]|19[78][0-9]|199[0-6])'
1965
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
0

Using standard grep syntax to extract lines ending with any substring number in the inclusive range 1965 to 1996 (this is also similar to the attempt by the user in the question):

grep -e '196[5-9]$' \
     -e '197[0-9]$' \
     -e '198[0-9]$' \
     -e '199[0-6]$'

This extracts lines that end with any of the numbers that you're interested in. Note that the expressions generally should be quoted.

To avoid matching e.g. 231974 (which matches 1974) at the end of the line, you may want to insert \< at the start of each number in the pattern:

grep -e '\<196[5-9]$' \
     -e '\<197[0-9]$' \
     -e '\<198[0-9]$' \
     -e '\<199[0-6]$'

This forces the number to be a word and not a substring of some other longer word.

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.