Find help in shell - that clears away duplicate files

I am so frustrated!!!

I want a nice command that clears away duplicate files:

find . -type f -regex '.*[0-9]{1,3}\..*' | xargs -I## rm -v '##'

should work in my opinion. But it finds nothing even though I have files that have the file name:

Scooby-Doo-1.txt
Himalaya-2.jpg
Camping 2009-12-12-33.jpg

and so on.

WHY?!?

Try:

find . -type f -regex '.*[0-9]\{1,3\}\..*'

or equivalent:

find . -type f -regex '[0-9]\{1,3\}\.'

But what do you mean with duplicate files?

-----
EDIT the latter is invalid since anchors are implicit !
EDIT 2 removed superflous closing brace in first example

I think that GNU find -regex has implicit ^ $ anchors, so the .* at both ends are needed.
{ } or \{ \} , if implemented at all, is not needed here.

find . -type f -regex '.*[0-9]\..*'

Traditional Unix find needs

find . -type f -name '*[0-9].*'
1 Like

Neither of the above is working.

find . -type f -regex '.*[0-9]\{1,3\}}\..*'

Escapes the {-parentheses and thus makes them part of the name. I want to use them to specify how many of the numbers should be in the file name and you have omitted the - sign (that might be a mistake though.
I.e they will match:

Myfile4{1,3}.txt

But not

Myfile-4.txt

----

find . -type f -regex '.*[0-9]\..*'

Has also forgot the - sign but, again, this might just be a mistake, but this regexp does find

Camping 2014-1.txt

but it will not find

Himalaya-22.txt

I want it to find 1 or more numbers after the - sign.

I want to match anything-1to3numbers.anything
The - sign has to be there, after the - sign there has to be 1-3 numbers and then a . and after the . anything.
I just cannot get it to work :frowning:

The -regex option with a find that supports it is BRE regex, which means that the curly braces will need to be escaped with a backslash otherwise it means a literal brace..

There was a closing brace too many in my example (one escaped, one unescaped). Corrected it in my post..

But that will match any occurrence of 1 or more numbers before the dot. To only match 1-3 numbers there needs to be another "anchor" before the numbers:

Try:

find . -type f -regex '.*-[0-9]\{1,3\}\..*'

to specify that the number is preceded with a dash, or

find . -type f -regex '.*[^0-9][0-9]\{1,3\}\..*'

to specify that the number is preceded by a character other than a number..

I apologize Scrutinizer, I didn't know that.
But it still dosn't work?!?

find . -type f -regex '.*-[0-9]\{1,3\}\..*'

gives me zero results :frowning: I am running this in /bin/bash under cygwin.
I also tried the exact same command in /bin/bash under Ubuntu, same thing - doesn't work.
Tried tcsh under Ubuntu, same thing - doesn't work.
CSH same thing - doesn't work.

I apologize for my rude answer since I really thought the \{ was the culprit and made the expression fail. But it has to be something else.

I have also tried to swap out the 1,3 to 1..3 and 1.3 to check the perl notation inside {} but that doesn't work either.

Frustration!

Strange, I get :

$ touch Scooby-Doo-1.txt Himalaya-2.jpg Camping 2009-12-12-33.jpg a-1234.txt
$ find . -type f -regex '.*-[0-9]\{1,3\}\..*'
./2009-12-12-33.jpg
./Himalaya-2.jpg
./Scooby-Doo-1.txt
$

Hold on, the above is on OSX with BSD find.

On Linux it does not work (just tested it)...
OK ON Linux it is GNU find an there the default regex type is emacs

EDIT: this seems to work on Linux:

find . -type f -regextype posix-basic -regex '.*-[0-9]\{1,3\}\..*'
find . -type f -regextype posix-extended -regex '.*-[0-9]{1,3}\..*'

Apparently the default "emacs" does not support the brace repetition operator, so it will probably be modeled after an old version of emacs..
So the -regextype option is required to change from the default regex type..

I personally never use regex with find, since it is not standardized..

--
EDIT: With the emacs default of GNU find this works:

find . -type f -regex '.*-[0-9][0-9]?[0-9]?\..*'

But that does not work with BSD find (unless the -E extended regex option is specified)..

1 Like
# touch ./2009-12-12-33.jpg ./Himalaya-2.jpg ./Scooby-Doo-1.txt
# find . -type f -regex '.*-[0-9]\{1,3\}\..*'
# find --version
find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Built using GNU gnulib version e5573b1bad88bfabcda181b9e0125fb0c52b7d3b
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS() CBO(level=0) 

Workaround:

# find . -type f -regex '.*-[0-9][0-9]*\..*'
./2009-12-12-33.jpg
./Himalaya-2.jpg
./Scooby-Doo-1.txt

---------- Post updated at 09:18 AM ---------- Previous update was at 09:11 AM ----------

The following is an exact replacement of \{1,3\} :

find . -type f \( -name '*-[0-9].*' -o -name '*-[0-9][0-9].*' -o -name '*-[0-9][0-9][0-9].*' \)

Woohoo!! It works! You rock! Thanks a gazillion Scrutinizer!

+goodie points from Sweden!