Removing orphaned sidecar files by extension

In a folder I might have the following types of filenames:

filename.imageExtension
filename.imageExtension.sidecarExtension
filename.sidecarExtension

The extensions are as follows:

imageExtension can be a number of extensions like: .nef, .raf, .orf, etc.

sidecarExtension can be a few extensions like: .xmp, .pts, .pp3, etc.

So in a folder I could, for example, have files like:

tree.nef
tree.nef.pp3

car.raf
car.xmp
car.raf.pp3

house.xmp
something.nef.pp3

In this case house.xmp and something.nef.pp3 are orphaned files that should be removed. What determines that those files are orphaned, is that there is no corresponding image file (a file with the same name but with an imageExtension and no sidecarExtension).

Is there a way to remove all the orphaned files, and only the orphaned files with a bash script?

I have been trying to do it with nested for loops and if statements like:

if [[ -e $(echo "$filename" | sed "s/"$imageExtension"/"$sidecarExtension"/g" ) ]]

or

if [[ -e $(echo "$filename" | sed "s/"$imageExtension""$sidecarExtension"/"$sidecarExtension"/g" ) ]]

but I never got the results I need.

1 answer

  • answered 2018-02-13 00:29 that other guy

    Here's one possible solution:

    shopt -s nullglob extglob;
    
    # Get all sidecar files
    for file in *.{xmp,pts,pp3}
    do
      # Generate all permutations of filenames that it may belong to,
      # and let globbing delete the ones that don't exist
      candidates=("${file%.*}"@() "${file%.*}".{nef,raf,orf}@()); 
    
      # If none exist, the file can be deleted
      [[ ${#candidates[@]} -eq 0 ]] && echo rm "$file"
    done
    

    It relies on the fact that with nullglob and extglob, "file"@() will expand into file if the file exists, or nothing if it does not.

    If it's not obvious, the echo must be removed to actually perform the deletion. Otherwise, it'll do a dry run and just say which files it would have deleted.