Як видалити файли JPG, але лише за наявності відповідного файлу RAW?


18

Мої ранні фотографії (Canon G2) - це всі JPG, але коли я отримав свій Nikon D90, спочатку я знімав у JPG, потім перейшов на RAW + JPG, а тепер хотів би перейти лише на RAW.

У мене буквально тисячі фотографій на моєму жорсткому диску. Фотографії знаходяться у підкаталогах (за датою) під однією каталогом під назвою Імпорт.

Я збираюся імпортувати всі ці фотографії в Lightroom 3.0, однак, я хотів би видалити всі файли JPG, але лише там, де вже є відповідний файл RAW (тобто я більше не хочу зберігати версії JPG та RAW однаковими. файл).

Якщо я можу це зробити легко в Lightroom (після імпортування всього, включаючи копії файлів JPG), це було б чудово. Було б також нормально, якби перед імпортом файлів був простий спосіб зробити це (але, сподіваємось, це не передбачає необхідності відвідувати кожен каталог, який шукає назви файлів з розширеннями JPG та NEF).

Хтось знає про спосіб зробити це (в Lightroom або за допомогою якогось інструмента / сценарію в Windows)?


Чи всі ваші jpg-файли та файли RAW мають принаймні однаковий рядок (до них можуть бути додані інші символи)? Наприклад, IMG_1234_portrait_picture.jpg & IMG_1234.CR2.
dpollitt

Я думаю, що всі мої пари JPG / NEF мають точно однакове ім’я файлу (крім розширення).
seanmc

3
Я буду голосувати , щоб перемістити це переповнення стека, де ви повинні отримати відповідь в протягом декількох хвилин =)
Anon

1
@anon: Як саме це належить до StackOverflow? Це, безумовно, тематичне питання тут, оскільки воно стосується інструментів управління зображеннями та редагування фотографій. Поза дотичним посиланням на сценарій ... це не має нічого спільного з програмуванням.
jrista

2
Я голосую, щоб закрити це питання поза темою, оскільки це насправді не фотографія, а керування файлами, які просто стають фотографіями. Питання та відповідь були б однаковими, якби два типи файлів, про які йдеться, були будь-якими іншими типами файлів, які можна було перекладати з однієї форми в іншу, наприклад, .doc та .pdf файли тощо
xiota

Відповіді:


24

У Windows перейдіть до папки та запустіть це у командному рядку:

for /f "delims==" %r in ('dir /b *.nef') do del "%~dpr%~nr.jpg" 2> nul

В основному він проходить через поточну папку, проходить через файли NEF та видаляє JPG, якщо він є. Він ігнорує будь-які помилки, якщо JPG немає.

Якщо ви хочете підпапки, включіть /sу dirкоманду.


3
Ідеально, дякую! Звичайно, перш ніж вперше запустити його, я змінив "del" на "echo". Тоді я побіг «допомога», щоб зрозуміти, що це робиться. Очевидно минуло давно, як я переглянув сценарій командного рядка, тому що я не мав уявлення, що команда "для" має стільки варіантів.
seanmc

Без проблем! Під час тестування я також використовував "echo" =) Щоб побачити більше результатів, видаліть "2> nul." Я мав намір зробити щось подібне для власних файлів NEF / JPG, і це була ідеальна можливість.
анонім

7

Ось модифікована версія сценарію Tomy's Python . Відмінності:

  • дозволено кілька необроблених розширень
  • видаляйте jpg, лише якщо пари знаходяться в одній папці (уникайте випадкового видалення jpg, названого як неочищений файл з іншої папки)
  • випадок нечутливий

#!/usr/bin/env python
# Script:      remove_jpg_if_raw_exists.py
#
# Description: This script looks in all sub directories for
#              pairs of JPG and RAW files.
#              For each pair found the JPG is moved to a
#              waste basket directory.
#              Otherwise JPG is kept.
#
# Author:      Thomas Dahlmann
# Modified by: Renaud Boitouzet

import os
import shutil

# define your file extensions here, case is ignored.
# Please start with a dot.
# multiple raw extensions allowed, single jpg extension only
raw_extensions = (".Dng", ".cR2", ".nef", ".crw")
jpg_extension = ".jPg"

# define waste basket directory here. Include trainling slash or backslash.
# Windows : waste_dir = "C:\path\to\waste\"
waste_dir = "/Users/marvin/Pictures/waste/"

##### do not modify below ##########

# find files
def locate(folder, extensions):
    '''Locate files in directory with given extensions'''
    for filename in os.listdir(folder):
        if filename.endswith(extensions):
            yield os.path.join(folder, filename)

# make waste basket dir
if not os.path.exists(waste_dir):
    os.makedirs(waste_dir)

# Make search case insensitive
raw_ext = tuple(map(str.lower,raw_extensions)) + tuple(map(str.upper,raw_extensions))
jpg_ext = (jpg_extension.lower(), jpg_extension.upper())

root=os.curdir
#find subdirectories
for path, dirs, files in os.walk(os.path.abspath(root)):
    print path
    raw_hash = {}
    for raw in locate(path, raw_ext):
        base_name = os.path.basename(raw)
        base_name = os.path.splitext(base_name)[0]
        raw_hash[base_name] = True

    # find pairs and move jpgs of pairs to waste basket
    for jpg in locate(path, jpg_ext):
        base_name = os.path.basename(jpg)
        base_name = os.path.splitext(base_name)[0]
        if base_name in raw_hash:
            jpg_base_name_with_ext = base_name + jpg_extension
            new_jpg = waste_dir + jpg_base_name_with_ext
            print "%s: %s = %s => %s" % (path, base_name, jpg, waste_dir)
            if os.path.exists(new_jpg):
                os.remove(jpg)
            else:
                shutil.move(jpg, new_jpg)

чудовий сценарій. Я буду використовувати його, тому що він має багато хороших відмовників. Однак вам слід додати цей рядок #!/usr/bin/env pythonна початку. В іншому випадку у мене були дивні помилки ImageMagick (здається, у мене mac відкритий .py-файли з ImageMagick)
therealmarv

Просто FYI: також здається, що це не працює, коли файли справді названі .jPg. Він також не працює, коли файли знаходяться на зовнішньому каталозі диска та сміття, наприклад у /homedir.
therealmarv


@therealmarv: насправді те, що відбувається з ImageMagick, полягає в тому, що сценарій відкривається в оболонці, а не ImageMagick, а "імпорт" - це назва інструмента ImageMagick.
Макс

6

Ось сценарій Python, який переміщує JPGфайли, коли не RAWіснує відповідного файлу. Корисно для Mac OS X !

import os
import shutil

raw_ext = '.CR2'
jpg_ext = '.JPG'
destination = '/Users/JohnSmith/Desktop/jpgs/'

for filename in os.listdir('.'):
    (shortname, extension) = os.path.splitext(filename)

    if extension == raw_ext:
        if os.path.isfile(shortname + jpg_ext):
            print 'Moving ' + shortname + jpg_ext + '...'
            shutil.move(shortname + jpg_ext, destination)

5
  • Створіть порожню бібліотеку
  • У головному меню Lightroom виберіть Правка> Налаштування (Windows) або Lightroom> Налаштування (Mac OS).
  • У Загальних налаштуваннях зніміть прапорець "Обробляти файли JPEG поруч із неочищеними файлами як окремими фотографіями"
    • Це має бути за замовчуванням.
  • Імпортуйте всі ваші файли (ви можете вибрати підпапки пошуку), повідомивши, щоб він перемістився на нове місце
  • JPG-файли, у яких є файли RAW, залишатимуться у вихідному місці, яке ви бажаєте видалити

Як я розумію, ескіз у світлій кімнаті може говорити про RAW + JPG, але JPG насправді не зберігається та не доступний.

Ви також можете написати досить простий пакетний сценарій з будь-якою мовою програмування.


2

Мені подобається сценарій bash для OS X ( Т.Тойвонен ), але я помітив, що є кілька проблем.

  • Це не сподобалось моїм каталогу імен, які містять пробіли. Це вимагало дещо іншого керування командою find.

  • Оригінальний сценарій працює лише для малих розширень. Я трохи вдосконалив цю частину сценарію для врахування розширень, які також є великими літерами. Зауважте, що він приймає лише пари DNG+JPGабо dng+jpgпари, і він буде ігнорувати будь-які комбінації, такі як DNG+jpgабо DnG+JpG.

  • Оригінальне рішення пропонувало лише одне wastedirрозташування, тоді як моє виправлення дозволяє створювати підкаталог у кожній гілці каталогу, хоча він проходить. Ви визначаєте ім'я каталогу перед циклом.

  • Мені подобається бачити, що відбувається, особливо коли mvабо rmвикористовуються команди;)

Заради простору я показую тільки останню частину сценарію, від завдання basedir, wastedirі петлі.

[...]

#Now set it as a basedir
BASEDIR=$arg
WASTEDIR=duplicates
find "$BASEDIR" -iname '*.dng' -print0 | while read -d $'\0' filename 
    do
    filepath="${filename%/*}"
    basename="${filename##*/}"
    prefix="${basename%%.*}"
    suffix=${filename##*.}
    if [[ "$suffix" =~ [A-Z] ]]; then rsuffix="JPG"; else rsuffix="jpg"; fi 
    if [ -e "$filepath/$prefix.$rsuffix" ]; then
        let counter="$counter+1"
        if (( $isSetE==1 )); then
            echo "FOUND: $filepath/$prefix.$rsuffix"
        fi
        if (( $isSetM==1 )); then
            echo "Moving $filepath/$prefix.$rsuffix to $filepath/$WASTEDIR"
            if [ ! -d "$filepath/$WASTEDIR" ]; then mkdir "$filepath/$WASTEDIR"; fi
            mv "$filepath/$prefix.$rsuffix" "$filepath/$WASTEDIR"
        fi
        if (( $isSetD==1 )); then
            echo "Removing duplicate $filepath/$prefix.$rsuffix"
            rm "$filepath/$prefix.$rsuffix"
        fi
    fi
done

Питання було позначено "windows", щоб ви могли сказати, як це можна зробити для роботи в типовій системі Windows. Наприклад, я запускаю Cygwin (і я планую краще розглянути цю відповідь, коли я працюю на робочому столі, щоб трохи змінити поведінку)
Chris H

2

Ось рішення для bash(Linux або Mac OS X). У Windows ви можете встановити Cygwin, щоб отримати копію bash.

keep=$(ls | grep -v ps | grep -A1 JPG | grep NEF)
for i in $keep ; do
   mv $i $i.keep
done

ls | egrep -v '(JPG|keep)' | xargs rm -f

change=$(ls | grep keep | sed 's/.keep//g')
for i in $change ; do
   mv $i.keep $i
done

2

Ось ще одна bashверсія з використанням find(Linux). Як і у відповіді Бена Пінгіллі , ви можете встановити Cygwin, щоб отримати баш на Windows.

#!/bin/bash
read -p "please enter file suffix for raw format (e.g ORF, NEF, CR2): " suffix

find . -type f -iname "*.${suffix}" | \
while read line
do
  lowercase=$(echo "$line" | sed "s/${suffix}/jpg/gi")
  uppercase=$(echo "$line" | sed "s/${suffix}/JPG/gi")

  if [ -f "${lowercase}" ]
  then
    rm -v "${lowercase}"
  elif [ -f "${uppercase}" ]
  then
    rm -v "${uppercase}"
  else
    echo "${line}: no jpg present"
  fi
done

1

Ось мій погляд на це питання. Дуже багато хороших ідей виходило з попередніх сценаріїв, про які згадувалося тут.

Це Баш скрипт для OS X . Він шукає файли, які існують з однаковим базовим файлом та dng+jpgрозширеннями. Якщо jpgзнайдено a з точно таким же ім’ям, як dngімені, відображається ( -e), файл переміщується ( -m) або видаляється ( -d).

Він буде проходити через папки, тож ви можете використовувати його для всього каталогу або лише його частин.

Для інших необроблених розширень файлів просто замініть *.dngу сценарії вашим бажаним розширенням.

Попередження: у вас можуть бути два різних зображення з однаковою назвою, але різним розширенням. Це неминучі жертви цього сценарію.

Ось як використовувати сценарій:

Usage: dng-jpg.sh [-m <path>] [-d <path>] [-e <path>] [-h]

-m: for move   (moves files to <path>/duplicates)
-d: for delete (deletes duplicate files)
-e: for echo   (lists duplicate files)
-h: for help 

Основне використання працює так:

$ ./dng-jpg.sh -e /Volumes/photo/DNG/2015

Це повторить усі назви jpgфайлів, які відповідають критеріям наявності обох dngі jpgфайлів з одним іменем.

Результат виглядатиме приблизно так:

Echo selected with path: /Volumes/photo/DNG/2015
/Volumes/photo/DNG/2015/03/18/2015-03-18_02-11-17.jpg
/Volumes/photo/DNG/2015/06/01/2015-06-01_05-10-50.jpg
/Volumes/photo/DNG/2015/06/01/2015-06-01_05-10-56.jpg
/Volumes/photo/DNG/2015/06/01/2015-06-01_05-11-39.jpg
/Volumes/photo/DNG/2015/06/01/2015-06-01_05-11-54.jpg
/Volumes/photo/DNG/2015/06/01/2015-06-01_05-12-26.jpg
/Volumes/photo/DNG/2015/06/01/2015-06-01_05-12-43.jpg
/Volumes/photo/DNG/2015/06/01/2015-06-01_05-13-21.jpg
/Volumes/photo/DNG/2015/06/01/2015-06-01_05-13-56.jpg
9 files found.

Тепер, якщо я хочу видалити файли, я б просто переключити -eна -d:

$ ./dng-jpg.sh -d /Volumes/photo/DNG/2015

Або якщо я хотів би перемістити файли в / дублікати, я би їх виконав -m.

$ ./dng-jpg.sh -m /Volumes/photo/DNG/2015

Тепер дублікати jpgфайлів будуть/Volumes/photo/DNG/2015/duplicates

Ось сценарій: dng-jpg.sh

#!/bin/bash

# Init variables
isSetM=0
isSetD=0
isSetE=0
isSetCount=0
counter=0

#Display usage info
usage() {

    cat <<EOF

Usage: dng-jpg.sh [-m <path>] [-d <path>] [-e <path>] [-h]

-m: for move   (moves files to <path>/duplicates)
-d: for delete (deletes duplicate files)
-e: for echo   (lists duplicate files)
-h: for help 

EOF
  exit 1
}

#Check for parameters
while getopts ":m:d:e:h" opt; do
  case ${opt} in
    m)
        isSetM=1
        let isSetCount="$isSetCount+1"
        arg=${OPTARG}
      echo "Move selected with path:" $arg
      ;;
    d)
        isSetD=1
        let isSetCount="$isSetCount+1"
        arg=${OPTARG}
      echo "Delete selected with path:" $arg
      ;;
    e)
        isSetE=1
        let isSetCount="$isSetCount+1"
        arg=${OPTARG}
      echo "Echo selected with path:" $arg
      ;;
    h)
        let isSetCount="$isSetCount+1"
        usage
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      usage
      ;;
    :)
      echo "Option -$OPTARG requires a directory argument." >&2
      usage
      ;;
    *)
      usage
      ;;
  esac
done

# If no parameters, show usage help and exit
if test -z "$1"; then
    usage
fi

# If multiple parameters (not counting -a), show usage help and exit
if (($isSetCount > 1)); then
    usage
fi

#Verify directory
if [ ! -d "$arg" ]; then
  echo "$arg is not a path to a directory." >&2
  usage
fi

#Now set it as a basedir
BASEDIR=$arg
WASTEDIR="$BASEDIR/duplicates/"
if (( $isSetM==1 )); then
    mkdir $WASTEDIR
fi

for filename in $(find $BASEDIR -name '*.dng' -exec echo {} \; | sort); do
   prefix=${filename%.dng}
    if [ -e "$prefix.jpg" ]; then
        let counter="$counter+1"
        if (( $isSetE==1 )); then
            echo "$prefix.jpg"
        fi
        if (( $isSetM==1 )); then
            mv $prefix.jpg $WASTEDIR
        fi
        if (( $isSetD==1 )); then
            rm $prefix.jpg
        fi
    fi
done

echo "$counter files found."

1

Ось bashскрипт для Mac OS X . Він може працювати в Linux з деякими змінами.

#!/bin/bash
read -p "Delete JPEGs when DNG exists? Ctrl-C to cancel. [Enter] to continue: "

for FILE in *.dng; do
  JPG_FILE=$(echo "$FILE" | sed "s/dng/jpg/g")
  rmtrash "${JPG_FILE}" 1>/dev/null
done

rmtrashце утиліта, яка переміщує файли в кошик, а не видаляти їх прямо. Ви можете отримати його від MacPorts таким чином:

sudo port install rmtrash

Якщо ви хочете цього уникнути, просто замініть rmtrashсценарій на rm, який негайно видалить JPGфайли.


1

Я написав наступний сценарій Python . У порівнянні зі сценарієм ttaveira , це робить додаткову роботу.

  • Дивиться в підкаталогах.
  • Створює каталог відходів призначення.
  • Видаляє файли, які вже є у каталозі відходів, щоб уникнути помилок переміщення.

# Script:      remove_jpg_if_raw_exists.py
#
# Description: This script looks in all sub directories for
#              pairs of JPG and RAW files.
#              For each pair found the JPG is moved to a
#              waste basket directory.
#              Otherwise JPG is kept.
#
# Author:      Thomas Dahlmann

import os, fnmatch

# define your file extensions here, case is ignored
raw_extension = "nef"
jpg_extension = "jpg"

# define waste basket directory here
waste_dir = "c:\image_waste_basked"

##### do not modify below ##########

# recursive find files 
def locate(pattern, root=os.curdir):
    '''Locate all files matching supplied filename pattern 
    in and below root directory.'''
    for path, dirs, files in os.walk(os.path.abspath(root)):
        for filename in fnmatch.filter(files, pattern):
            yield os.path.join(path, filename) 

# get base names from raw's
raw_hash = {}
for raw in locate("*." + raw_extension):
    base_name = os.path.basename(raw)
    base_name = os.path.splitext(base_name)[0]
    raw_hash[base_name] = True

# make waste basket dir
if not os.path.exists(waste_dir):
    os.makedirs(waste_dir)

# find pairs and move jpgs of pairs to waste basket    
for jpg in locate("*." + jpg_extension):
    base_name = os.path.basename(jpg)
    base_name = os.path.splitext(base_name)[0]
    if base_name in raw_hash:
        jpg_base_name_with_ext = base_name + "." + jpg_extension
        new_jpg = waste_dir + "\\" + jpg_base_name_with_ext
        print "%s => %s" % (jpg, waste_dir)
        if os.path.exists(new_jpg):
            os.remove(jpg)
        else:
            os.rename(jpg, new_jpg)

2
Привіт, ласкаво просимо до Photo.SE. Чим ваша відповідь відрізняється від відповіді ttaveira ?
Saaru Lindestøkke

Сценарій виконує додаткову роботу: також шукає у всіх підкаталогах, створює каталог відходів призначення для jpg, якщо його не існує, і він видаляє jpg, а не переміщується, якщо він вже є в каталозі відходів (уникає помилок переміщення)
Tomy

0

Працюючи над Mac OS X , у попередніх відповідях я пропустив перевірку обґрунтованості на "той самий вміст". У мене були дублюючі назви різних зображень, тому що я забув включити лічильник зображень у своїй камері. Ось моя версія, яка перевіряє інформацію EXIF ​​на той самий час зйомки:

Вам потрібно бігти

sudo port install rmtrash exiv2

перш ніж використовувати наступну команду. Це було написано для порівняння JPGз NEFфайлами з мого Nikon D90. Відрегулюйте розширення файлів відповідно до своїх потреб.

find . -name \*.NEF |sed s/\.NEF/.JPG/g | xargs find 2>/dev/null | \
xargs perl -e 'foreach(@ARGV) {my $jpg=$_;my $nef=s/\.JPG/.NEF/r; my $tjpg = `exiv2 -g Exif.Photo.DateTimeOriginal -pt $jpg`; my $nef=s/\.JPG/.NEF/r; my $tnef = `exiv2 -g Exif.Photo.DateTimeOriginal -pt $nef`; if($tjpg eq $tnef) {print "$jpg\n"}}' | \
xargs rmtrash

без перевірки обгрунтованості вся справа стала б дуже короткою підводкою:

find . -name \*.NEF |sed s/\.NEF/.JPG/g | xargs find 2>/dev/null | xargs rmtrash
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.