I'd shoot my camera in RAW/JPEG mode, and since the RAW images are huge (in file size), it takes forever to preview them so I preview the JPEGs, and delete those which I don't want.

For instance, if I have:


I'd like to delete the .CR2 which don't have a matching .jpg (images 3 through 5 in this example).

I came across the following code:

rm *.CR2(e:'[[ ! -e ${REPLY%.CR2}.jpg ]]':)

but it doesn't work on my machine. I've not touched Bash in donkey's years so I'm at a loss at trying to resolve it.

I get the error:

-bash: syntax error near unexpected token `('

Can anybody point me in the right direction, please?

  • 4
    That command is for zsh, not bash. – Kevin Apr 9 '18 at 22:30
  • That'll be why it doesn't work! Thanks Yurij :) – Dave Melia Apr 9 '18 at 22:31
  • @DaveMelia what do you mean? :) – Yurij Goncharuk Apr 9 '18 at 22:34
  • @YurijGoncharuk I mean, if it's for zsh and not bash (like you said)... That's why it doesn't work for me (Because I'm running it in bash) – Dave Melia Apr 9 '18 at 22:35
  • 1
    Comment about zsh was from @Kevin :) – Yurij Goncharuk Apr 9 '18 at 22:36

Just use a loop:

for x in *.CR2
    [ -e "${x%.CR2}.jpg" ] || echo rm "$x"

This looks at every .CR2 file and calls it x. ${x%.CR2} expands to the filename with .CR2 removed, so we add the .jpg extension on and check whether that exists with -e. If it doesn't, we remove the original .CR2 file.

The above has an extra echo in it so you can check it's picking the files you want before you actually delete anything. You can put it all on one line if you want:

for x in *.CR2 ; do [ -e "${x%.CR2}.jpg" ] || echo rm "$x"; done

and it'll be easy to edit interactively.

Some shells have more powerful parameter expansion that might be able to do this, but Bash isn't one of them. I suspect the code you found was targeting one of those.

| improve this answer | |
  • gold answer! thanks! – chema Aug 2 '19 at 10:01

Not the answer you're looking for? Browse other questions tagged or ask your own question.