Home > database >  Bash Globbing Pattern Matching for Imagemagick recursive convert to pdf
Bash Globbing Pattern Matching for Imagemagick recursive convert to pdf

Time:07-10

I have the following 2 scripts, that recursively convert folders of images to pdf's for my wifes japanese manga kindle using find and Imagemagick convert:

#!/bin/bash
_d="$(pwd)"
echo "$_d"
find . -type d -exec echo "Will convert in the following order: {}" \;
find . -type d -exec echo "Converting: '{}'" \;  -exec convert '{}/*.jpg' "$_d/{}.pdf" \; 

and the same for PNG

#!/bin/bash
_d="$(pwd)"
echo "$_d"
find . -type d -exec echo "Will convert in the following order: {}" \;
find . -type d -exec echo "Converting: '{}'" \;  -exec convert '{}/*.png' "$_d/{}.pdf" \; 

Unfortunately I am not able make one universal script that works for all image formats. How do I make one script that works for both ? I would also need JPG,PNG as well as jpeg,JPEG

Thx in advance

CodePudding user response:

You can do more complicated actions if you turn the find exec into a bash function (or even a standalone script).

#!/bin/bash

do_convert()(
    shopt -s nullglob
    for dir in "$@"; do
        files=("$dir"/*.{jpg,JPG,PNG,jpeg,JPEG})
        if [[ -z $files ]]; then
            echo 1>&2 "no suitable files in $dir"
            continue
        fi
        echo "Converting $dir"
        convert "${files[@]}" "$dir.pdf"
    done
)
export -f do_convert

pwd

echo "Will convert in the following order:"
find . -type d

# find . -type d -exec bash -c 'do_convert {}' \;
find . -type d -exec bash -c 'do_convert "$@"' -- {} \  
  • nullglob makes *.xyz return nothing if there is no match, instead of returning the original string unchanged
  • p/*.{a,b,c} expands into p/*.a p/*.b p/*.c before the * are expanded
  • x()(...) instead of the more normal x(){...} uses a subshell so we don't have to remember to unset nullglob again or clean up any variable definitions
  • export -f x makes function x available in subshells
  • we skip conversion if there are no suitable files
  • with the slightly more complicated find command, we can reduce the number of invocations of bash (probably doesn't save a great deal in this particular case)

CodePudding user response:

I wouldn't use find at all, just a loop:

#!/use/bin/env bash

# enable recursive globs
shopt -s globstar

for dir in **/*/; do
    printf "Converting jpgs in %s\n" "$dir"
    convert "$dir"/*.jpg "$dir/out.pdf"
done

If you want to combine .jpg and .JPG in the same pdf, add nocaseglob to the shopt line. Add .jpeg to the mix? Add extglob and change "$dir"/*.jpg to "$dir"/*.@(jpg|jpeg)

  • Related