1

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.

0

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 with find -regex ".*[09]x[0-9][0-9][0-9].jpg" – Mike Mar 9 '18 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" – user1404316 Mar 9 '18 at 16:35
1

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. – Mike Mar 9 '18 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 '18 at 16:07

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.