# Find a pattern with no repeated numbers in egrep

I to find a regular expression to match all digit sequences which has no repeated digit. Example:

198345 -> matched.

198315 -> not matched (1 repeated twice )

How can I achieve this in `grep\egrep`?

Interesting question. Thank you. The answer I found a little bit creepy:

``````egrep -v '([0-9])[0-9]*\1'
``````

pattern find the occurrence of digit `[0-9]`, save it to `\1` and check for non repetition. So it finds any digit followed by the same digit. Use `-v` for inverse

• Properly you should add `| grep '[0-9]'` at the end. Commented Nov 8, 2016 at 6:12

If you need to do it with regex, see Stephane's wonderful answer to a similar question.

If regex is not a must, I offer you a Perl alternative:

``````perl -nle '
\$digits{\$_}++ for /([0-9])/g;
@repeated = grep { \$digits{\$_} > 1 } keys %digits;
print @repeated? "":"\$_"
%digits = ();
' your_file
``````

This assumes `your_file` has one number per line and will print out only those numbers whose digits are unique.

Edit:

Below the same numbers must appear consecutively: they match 1123456 (consecutive 1s) but not 1213456 (non-consecutive 1s):

A lame solution is this:

``````cat testfile |  grep [0-9] | grep -v "0\{2,\}" | grep -v "1\{2,\}" | grep -v "2\{2,\}"  | grep -v "3\{2,\}"  | grep -v "4\{2,\}"  | grep -v "5\{2,\}"  | grep -v "6\{2,\}"  | grep -v "7\{2,\}"  | grep -v "8\{2,\}"  | grep -v "9\{2,\}"
``````

The first `grep` matches numbers and the rest 10 `grep`ensure that every number appears only once.

A more compact but still lame way is this:

``````cat test |  grep [0-9] | grep -v "1\{2,\}\|2\{2,\}\|3\{2,\}\|4\{2,\}\|5\{2,\}\|6\{2,\}\|7\{2,\}\|8\{2,\}\|9\{2,\}\|0\{2,\}"
``````

`testfile` must have one word per line.

• The `grep`s are not actually doing what you think: they discard numbers with no repeating consecutive digits. That's not quite what the OP wants. In any case, your assumption (1 number per line) renders `grep [0-9]` redundant. Commented Jun 3, 2014 at 20:11
• @Joseph Yeap, I should have said "one word per line" instead of "one number per line". Thanks! Commented Jun 3, 2014 at 20:15
• Ah, they match consecutive digits. :( Yes it is not correct. Commented Jun 3, 2014 at 20:42
``````grep '\([[:digit:]]\) *\1 *\1'
``````

It takes a digit `[[:digit:]]` and remembers it `\( ... \)`. It than tries to match any number of spaces `*` (including none at all), remember character `\1`, any number of spaces, the remembered character. You can try running it with `--color=auto` to see what parts of the input it matched.