通过 exiftool 同时删除多个属性

通过 exiftool 同时删除多个属性

我一直在想出一个脚本来从等于“OLYMPUS DIGITAL CAMERA”的 JPEG 文件中删除任何 EXIF/IPTC/XML 元数据。对于那些不知道的人来说,奥林巴斯相机在所有照片中都设置了此属性,并且没有选项将其关闭。更糟糕的是,虽然我已经设置了 Lightroom 预设以在导入时或在编辑现有图像时将其删除,但最近的 LR 版本中似乎存在一个错误,在导出图像时仍然在图像描述、标题摘要和描述中嵌入该属性。图像转 JPEG。

因此,像许多奥林巴斯用户一样,我希望它永远消失,我编写了一个非常简单的 bash 脚本来做到这一点。它主要设计用于在我的 QNAP NAS 上运行,但可以轻松修改以在不同环境中工作。它在特定图像上的 exiftool 输出中搜索“OLYMPUS DIGITAL CAMERA”的任何实例,然后删除该 attiobute。

#!/usr/bin/env bash
IFS=$'\n'; ## Handle spaces in file paths/names
directory="/share/CE_CACHEDEV1_DATA/homes/admin/Images/Final Albums/"
exiftool="/share/CE_CACHEDEV1_DATA/.qpkg/Entware/bin/exiftool"
find="/opt/bin/find"

for f in $($find "$directory" -type f -iname '*.jp*g');
do
    #echo "$f"
    for field in $($exiftool -s "$f" | grep "OLYMPUS DIGITAL CAMERA" | awk -F: '{ print $1 }' | sed 's/ *$//g');
    do
        echo "Removing $field on $f"
        $exiftool -overwrite_original -"$field"= "$f"
    done
done

唯一的问题是它非常慢。对 exiftool 的任何调用似乎都需要 0.5 秒,因此我想通过一次性删除所有属性来提高效率,而不是循环每个匹配属性并一一删除它们。这是脚本的第二版。

#!/usr/bin/env bash
IFS=$'\n'; ## Handle spaces in file paths/names
directory="/share/CE_CACHEDEV1_DATA/homes/admin/Images/Final Albums/"
exiftool="/share/CE_CACHEDEV1_DATA/.qpkg/Entware/bin/exiftool"
find="/opt/bin/find"
for f in $($find "$directory" -type f -iname '*.jp*g');

do
    #echo "$f"
    fieldstring=''
    for field in $($exiftool -s "$f" | grep "OLYMPUS DIGITAL CAMERA" | awk -F: '{ print $1 }' | sed 's/ *$//g');
    do
        fieldstring="${fieldstring}-$field= "
    done
    echo $fieldstring
    $exiftool -overwrite_original $fieldstring $f
done

问题是它似乎一次只能删除一个属性。 $fieldstring 的输出是:

-ImageDescription= -Caption-Abstract= -Description=

但我也尝试过用单引号和双引号包围要删除的标签,但都没有帮助。

我想这也许是 eximtool 的限制。但我编写了另一个脚本,它只是擦除了 3 个主要属性(图像描述、标题摘要和描述),而没有对其包含的内容进行任何测试,并且效果很好!

#!/usr/bin/env bash
IFS=$'\n'; ## Handle spaces in file paths/names
directory="/share/CE_CACHEDEV1_DATA/homes/admin/Images/Final Albums/"
exiftool="/share/CE_CACHEDEV1_DATA/.qpkg/Entware/bin/exiftool"
find="/opt/bin/find"
for f in $($find "$directory" -type f -iname '*.jp*g');
do
    echo "$f"
    $exiftool -overwrite_original -"Description"= -"Caption-Abstract"= -"ImageDescription"= "$f"
done

所以我相当确定这是我犯过的那些愚蠢的、眼前的错误之一,但经过两个小时的尝试弄清楚后,我不知所措。有人能发现一个愚蠢的错误吗?我已经输出了 $fieldstring ,它对我来说看起来不错,所以我认为这是我缺少的 bash 脚本,因此在这里发布!

非常感谢!

答案1

我已经接受了您的要求并编写了一个新的脚本。您可能需要自定义,set -- .以便将点替换为图像的默认路径。或者您可以在命令行上提供图像目录

#!/usr/bin/env bash
#
export PATH=/opt/bin:$PATH           # Prefer commands from Entware

[[ $# -eq 0 ]] && set -- .           # Replace . with default path to source of images
unwanted='OLYMPUS DIGITAL CAMERA'    # phrase to match and remove

find "$@" -type f \( -iname '*.jpg' -o -iname '*.jpeg' \) -print |
    while IFS= read -r file
    do
        # Get list of fields containing the unwanted phrase
        fields=($(exiftool -s "$file" | awk -v x="$unwanted" '$0 ~ x {print $1}'))

        # Skip files with no issues
        [[ ${#fields[@]} -eq 0 ]] && continue

        # Convert fields to exiftool parameters
        exifargs=()
        for field in "${fields[@]}"
        do
            exifargs+=("-$field=")
        done

        # Apply the conversion
        echo "Removing ${fields[@]} from: $file"
        echo exiftool -overwrite_original "${exifargs[@]}" "$file"
    done

# Done
exit 0

当你很高兴它会做你想做的事情时,将echo其删除。echo exiftool

我们在这里使用 bash 数组。例如,fields是一个包含 EXIF 键名称列表的数组,其中包含文本OLYMPUS DIGITAL CAMERA,是删除字段值exifargs的相应参数列表。我们可以直接exiftool生成,但似乎更容易显示这两个步骤发生的情况。exifargsawk

相关内容