Question

I have multiple series of jpegs. Each series is in its own folder. I wish to convert each series into a single pdf. I would further like the pdf to have the same name as the folder it is in.

To do this on the command line in each folder I can use the following command:

convert *.jpg `echo ${PWD##*/}`.pdf

I would like to do it from the top level folder with a bash script.

Was it helpful?

Solution

You might want to use find for this:

find . -type d -exec bash -c 'cd "$0" || exit; shopt -s nullglob; f=( *.jpg ); ((${#f[@]})) && echo convert "${f[@]}" "${PWD##*/}.pdf"' {} \;

This will recurse into each subdirectory and for each execute the Bash commands:

cd "$0" || exit
shopt -s nullglob
f=( *.jpg )
((${#f[@]})) && echo convert "${f[@]}" "${PWD##*/}.pdf"
  • The $0 will expand to the argument given to Bash, i.e., the directory found by find. The exit is here as a security in case it's impossible to cd in there: you don't want to have random commands executed in this case.
  • shopt -s nullglob: if there are no matches, the globs expand to nothing. Useful if there are subdirectories with no filenames ending in .jpg.
  • build an array f of all the filenames in current directory with a filename ending in .jpg. This array is empty if there are no such files (thanks to the nullglob shell option).
  • If the array f is non-empty, execute the command:

    echo convert "${f[@]}" "${PWD##*/}.pdf"
    

    (by the way, your echo ${PWD##*/}.pdf is wrong, see below).

I put an echo in front of convert, so that nothing is actually performed; the command is shown on standard output, for you to visually check if everything works as you expect. If this is the case, just remove the echo!


You asked in a comment: why do you say the following line is wrong?

convert *.jpg `echo ${PWD##*/}`.pdf

you even say since it worked. To work and to be correct are not equal in computer science. The it works sentence should be understood in the full following form: it works until it fails. The most obvious case where this fails is if the directory name contains spaces: imagine a directory name of hello world then convert will see hello as an argument on its own, and world.pdf as the last argument. Very likely not what you want. Besides, the following is correct (and shorter and easier to understand):

convert *.jpg "${PWD##*/}.pdf"
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top