Bash

通過 exiftool 同時刪除多個屬性

  • January 4, 2022

我一直想出一個腳本來從等於“OLYMPUS DIGITAL CAMERA”的JPEG文件中刪除任何EXIF/IPTC/XML元數據。對於那些不知道的人,奧林巴斯相機在所有照片中都設置了這個屬性,沒有關閉它的選項。更糟糕的是,雖然我已經設置了 Lightroom 預設以在導入時或在編輯現有圖像時將其刪除,但在最近的 LR 版本中似乎存在一個錯誤,在導出圖像時仍將屬性嵌入到 ImageDescription、Caption-Abstract 和 Description圖像為 JPEG。

因此,像許多 Olympus 使用者一樣,我希望它永遠被淘汰,並且我編寫了一個非常簡單的 bash 腳本來做到這一點。它主要設計用於在我的 QNAP NAS 上執行,但可以輕鬆修改以在不同環境中工作。它在特定圖像的 exiftool 輸出中搜尋“OLYMPUS DIGITAL CAMERA”的任何實例,然後刪除該屬性。

#!/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 秒,因此我想通過一次性刪除所有屬性來提高效率,而不是循環每個匹配的屬性並逐個刪除它們。所以這是腳本的第 2 版。

#!/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 個主要屬性(ImageDescription、Caption-Abstract 和 Description),而沒有對它們包含的內容進行任何測試,而且效果很好!

#!/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

所以我很確定這是我犯的那些愚蠢的、直接犯下的錯誤之一,但經過 2 小時的努力想弄清楚,我不知所措。誰能發現一個愚蠢的錯誤?我已經輸出了 $fieldstring 並且對我來說看起來不錯,所以我認為這是我缺少的 bash 腳本,因此在這裡發布!

非常感謝!

我已經接受了您的要求並編寫了一個新腳本。您可能需要自定義 ,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 鍵名列表的數組,其中包含 text OLYMPUS DIGITAL CAMERA,並且是刪除欄位值exifargs的相應參數列表。exiftool我們可以exifargs直接生成,awk但顯示這兩個步驟發生了什麼似乎更容易。

引用自:https://unix.stackexchange.com/questions/684867