The accepted answer is fine if you can use lookarounds. However, there is also another approach to solve this problem.
If we look at the widely proposed regex for this question:
.*[^a]$
We will find that it almost works. It does not accept an empty string, which might be a little inconvinient. However, this is a minor issue when dealing with just a one character. However, if we want to exclude whole string, e.g. "abc", then:
.*[^a][^b][^c]$
won't do. It won't accept ac, for example.
There is an easy solution for this problem though. We can simply say:
.{,2}$|.*[^a][^b][^c]$
or more generalized version:
.{,n-1}$|.*[^firstchar][^secondchar]$
where n is length of the string you want forbid (for abc
it's 3), and firstchar
, secondchar
, ... are first, second ... nth characters of your string (for abc
it would be a
, then b
, then c
).
This comes from a simple observation that a string that is shorter than the text we won't forbid can not contain this text by definition. So we can either accept anything that is shorter("ab" isn't "abc"), or anything long enough for us to accept but without the ending.
Here's an example of find that will delete all files that are not .jpg:
find . -regex '.{,3}$|.*[^.][^j][^p][^g]$' -delete