What the following command should do, is to search for all invoice pdf files and check if there is a thumbnail file inside the same directory. If not, it should print the directory. Later I will add a command which will create the thumbnails.

find . -maxdepth 2 -type f -name "invoice_*.pdf" -exec sh -c '[ -f "$(dirname {})/thumbnail.jpeg" ] || echo {}' ';'

The command is working, but I besides the filepath I see the following

sh: 1: Syntax error: "(" unexpected (expecting ")")

I guess the filepath gets interpreted as command.

  • maybe you should use -execdir instead of -exec, then you wouldn't need to use $(dirname {}) (you can just test [ -f ./thumbnail.jpeg ]) – cas Feb 15 '18 at 5:54
  • -execdir is a good idea, but I need the path to the pdf file. when I use -execdir, {} contains only the filename like ./invoice_19805.pdf – Aley Feb 15 '18 at 8:42
  • and it's not solving the described problem :( – Aley Feb 15 '18 at 8:42
  • are there any ( or ) characters in the invoice_*.pdf filenames? try double-quoting the {} in the echo statement. – cas Feb 15 '18 at 10:09

You have a ( in one of your files names and are not quoting.


find . -mindepth 3 -maxdepth 3 -type f -exec sh -c '[ -f "$(dirname '"'{}'"')/thumbnail.jpeg" ] || echo "{}"' \;

The quotception going on with '"'{}'"' is to pass double quotes through to the dirname command in case there is a ( in the file name. The '[ -f .. ]' command also needs double quotes and the echo command also needs quotes!

It may be easier to use find to call a script and pass it the path as an argument so you don't have to think about multiple layers of quoting and substitution. For example (not tested):

$ cat script
#!/bin/bash --
dir=$(dirname "${1}")
[ -f "${dir}/thumbnail.jpeg" ] || echo "${1}" 

$ find . -mindepth 3 -maxdepth 3 -type f -exec ./script '{}' \;

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.