我一直在想出一个脚本来从等于“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
生成,但似乎更容易显示这两个步骤发生的情况。exifargs
awk