0

I found this script to convert images to webp format.

#!/bin/bash -x

converting JPEG images

find $1 -type f -and ( -iname ".jpg" -o -iname ".jpeg" )
-exec bash -c ' webp_path=$(sed 's/.[^.]*$/.webp/' <<< "$0"); cwebp -quiet -q 90 "$0" -o "$webp_path"; rm -rf $webp_path;' {} ;

The folder which is provided as input is as below.

root@ip-10-0-1-46:/var/images/newlocallego/12345# tree
.
└── 01234
    ├── 001.jpg
    ├── 002.jpg
    ├── index.htm
    └── main.jpg

1 directory, 4 files

i am executing as ./webpconvert.sh /var/images/newlocallego/12345

However, its neither creating the webp files nor removing the jpg files and not giving any error. What am i missing.

jmort253
  • 295

1 Answers1

1

You are immediately removing your output file after creating it. You also have issues with quoting in the bash -c script's command substitution around sed, and there are a few instances of variables not being quoted at all.

Corrected variant:

find "$@" -type f \( -iname '*.jpg' -o -iname '*.jpeg' \) -exec bash -c '
    for pathname do
        cwebp -quiet -q 90 -o "${pathname%.*}.webp" -- "$pathname" &&
        rm -f -- "$pathname"
    done' bash {} +

This makes the operation more efficient by calling bash -c with batches of found files instead of once per file.

The original file is not removed unless cwebp exited successfully. The .webp filename suffix replaces the original filename suffix by means of a standard parameter substitution, rather than by using sed. Note that -r is not needed with rm when removing files.

The script now also support taking multiple directories on the command line.

Without using find, in bash:

shopt -s nullglob dotglob nocaseglob
shopt -s globstar

for dirpath do for pathname in "$dirpath"/*/.{jpg,jpeg}; do [ ! -f "$pathname" ] && continue

    cwebp -quiet -q 90 -o &quot;${pathname%.*}.webp&quot; -- &quot;$pathname&quot; &amp;&amp;
    rm -f -- &quot;$pathname&quot;
done

done

The only difference is that this bash loop would also process symbolic links to regular files matching the patterns. If that is an issue, then change the -f test in the inner loop to

if [ ! -f "$pathname" ] || [ -h "$pathname" ]; then
    continue
done
Kusalananda
  • 333,661