图像转换 bash 脚本不起作用

图像转换 bash 脚本不起作用

我发现这个脚本可以将图像转换为 webp 格式。

#!/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;' {} \;

作为输入提供的文件夹如下。

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

1 directory, 4 files

我正在执行./webpconvert.sh /var/images/newlocallego/12345

但是,它既不创建 webp 文件,也不删除 jpg 文件,并且没有给出任何错误。我缺少什么。

答案1

您将在创建输出文件后立即将其删除。您还遇到了在bash -c脚本的命令替换 around中引用的问题sed,并且有一些变量的实例根本没有被引用。

修正后的变体:

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 {} +

bash -c通过批量调用找到的文件而不是每个文件调用一次,可以使操作更有效率。

cwebp除非成功退出,否则不会删除原始文件。文件.webp名后缀通过标准参数替换的方式替换原始文件名后缀,而不是使用sed.请注意,删除文件时-r不需要。rm

该脚本现在还支持在命令行上获取多个目录。

在不使用find, 的情况下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 "${pathname%.*}.webp" -- "$pathname" &&
        rm -f -- "$pathname"
    done
done

唯一的区别是该bash循环还将处理与模式匹配的常规文件的符号链接。如果这是一个问题,则将-f内部循环中的测试更改为

if [ ! -f "$pathname" ] || [ -h "$pathname" ]; then
    continue
done

相关内容