I have a lot of folders with files ending with "-105x135.jpg", "-410x410.jpg" etc., "780-105x135.jpg" and "candyswing-2-klein-ohrringe-schale-038-135x160.jpg" for example which i need to find and delete, using online regex I've created this pattern: [0-9]x..[0-9].jpg
, but find . -regex '[0-9]x..[0-9].jpg'
didn`t show any results.
2 Answers
According to the man
page, the -regex
option is a match on the entire path, ie. the entire file name and also the entire directory-path portion, so you would need to precede your regex with .*
. There are several explicit examples in the man
page.
Also, keep in mind the option -regextype
. The default (per the man
page) is emacs
, but other options are posix-awk
, posix-basic
, posix-egrep
and posix-extended
. Knock yourself out.
-
Thanks! It did work, but besides adding
.*
I needed to replace periods with[0-9]
, for some reason periods didn't work. I ended up withfind -regex ".*[09]x[0-9][0-9][0-9].jpg"
– MikeMar 9, 2018 at 15:35 -
Great to hear. If you're game to continue experimenting, try
".*[09]x[0-9]+.jpg"
and".*[09]x[0-9]{3}.jpg"
Mar 9, 2018 at 16:35
Another option would be to use bash's globstar option:
shopt -s globstar
to list:
ls **/*[0-9][0-9][0-9]x[0-9][0-9][0-9].jpg
or remove:
rm **/*[0-9][0-9][0-9]x[0-9][0-9][0-9].jpg
the files.
The glob pattern above is slightly different that the regex you provided; the regex would allow any two characters after the x
, not strictly numbers. In other words, a file named: somefile-135xyz9.jpg
would match the regex, but not the above glob.
The glob recursively (**
) matches files that:
- start with anything (
*
) - have three numbers (three
[0-9]
) - followed by an
x
- followed by three numbers
- followed by
.jpg
One risk to this approach is if/when the number of matching files exceeds the command-line argument space. In that case, you could save the filenames in an array, then loop through the array individually.
To investigate:
files=(**/*[0-9][0-9][0-9]x[0-9][0-9][0-9].jpg)
for file in "${files[@]}"; do echo Would: rm -- "$file"; done
To remove:
files=(**/*[0-9][0-9][0-9]x[0-9][0-9][0-9].jpg)
for file in "${files[@]}"; do rm -- "$file"; done
-
Unfortunately, it gave me
bash: /usr/bin/ls: Argument list too long
error.– MikeMar 9, 2018 at 14:37 -
@Mike, I've added a workaround to the end of my post, in case it's useful for you.– Jeff Schaller ♦Mar 9, 2018 at 16:07