0

I use this commandline to convert jpegs to pdfs inside a folder.

for f in *.jpg; do  echo "Converting $f"; convert "$f" "$(basename "$f" .jpg).pdf"; done

However, I would like to convert all .jpg from several folders to .pdf located inside the samefolder. I need a bash command which says "go inside folder A, launch the conversion to pdf and when it is done, go to folder B and do the same".

Also jpeg file could be ended by .jpg or .JPG.

My folder structure is such as:

Folder A
    File1.jpg
    File1.jpg
    File1.jpg
    File1.jpg
    File1.jpg
Folder B
    File1.jpg
    File1.jpg        
    File1.jpg
    ...

Any idea about how to achieve this?

  • 1
    You would use find with the -execdir action. – glenn jackman Feb 25 at 15:52
2

Updated to allow file names *.jpg and *.JPG according to updated question:
Use -iname for case insensitive comparison, and variable expansion with pattern ${file%.[jJ][pP][gG]}. This will actually match .jpg in any capitalization, e.g. .JpG.

Assuming Folder A and Folder B are in the current directory and you want to do the same in all directories recursively:

find . -type f -iname \*.jpg | while read -r file
do
    echo "Converting $file"
    convert "$file" " ${file%.[jJ][pP][gG]}.pdf"
done

Or if you want to specify the directory names

find "Folder A" "Folder B" type f -iname \*.jpg | ...

If you don't have any subdirectories named *.jpg you can leave out the -type f.

If you don't want to do the conversion recursively in subdirectories of Folder A etc. you might have to add a -maxdepth condition.

  • Thanks, but I have this error : $ find . -type f -name \*.JPG | while read -r file ; do echo "Converting $f"; convert "$f" "$(basename "$f" .JPG).pdf"; done Converting *.JPG convert-im6.q16: unable to open image *.JPG': Aucun fichier ou dossier de ce type @ error/blob.c/OpenBlob/2874. convert-im6.q16: no images defined *.pdf' @ error/convert.c/ConvertImageCommand/3258. – ppr Feb 25 at 17:28
  • What does the while read -r file? – ppr Feb 25 at 17:32
  • 1
    @ppr Please check the variable names. You mixed file and f. In my proposal I used "${file%.jpg}.pdf" instead of calling basename because basename would strip the directory name. Do you want to find *.JPG in capitals only or both *.jpg and *.JPG? Please edit your question to add more information. See mywiki.wooledge.org/BashFAQ/001 – Bodo Feb 25 at 17:37
  • Indeed, I mixed file and f, sorry. It works now. I have .jpg and .JPG (I updated my question about that). – ppr Feb 25 at 17:45
  • I don't remember: is it normal to have single paged pdf output (and not multi-paged)? – ppr Jun 19 at 16:36
3

What you have asked for is not a recursive operation, so it can be handled by a trivial adaptation of your original code:

for f in */*.jpg */*.JPG; do echo "Converting $f"; convert "$f" "${f%.*}.pdf"; done

If this is for production code rather than a quick one-off I would protect the possibility that there were no jpg or JPG files, or that the PDF had already been generated. Add or tweak to your satisfaction, of course:

for f in */*.jpg */*.JPG
do
    if [[ -f "$f" ]] && [[ ! -f "${f%.*}.pdf" ]]
    then
        echo "Converting $f"
        convert "$f" "${f%.*}.pdf"
    fi
done
  • 1
    and given the recent edit to the question, just change both "jpg" to "JPG" – Jeff Schaller Feb 25 at 19:19
  • Is it supposed to make multipage pdfs ? I obtained single paged pdfs. – ppr Jun 19 at 16:06
  • @ppr it creates one pdf per image, just as you asked. – roaima Jun 19 at 17:59

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.