Как удалить файлы 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)?

seanmc
источник
Все ли ваши JPG-файлы и RAW-файлы содержат как минимум одну и ту же строку (другие символы могут быть добавлены к любому)? Например, IMG_1234_portrait_picture.jpg & IMG_1234.CR2.
dpollitt
Я думаю, что все мои пары JPG / NEF имеют одно и то же имя файла (за исключением расширения).
seanmc
3
Я буду голосовать , чтобы переместить это переполнение стека, где вы должны получить ответ в течение нескольких минут =)
Anon
1
@anon: Как именно это относится к StackOverflow? Это, безусловно, вопрос по теме, поскольку он касается инструментов управления изображениями и редактирования фотографий. Вне тангенциальной ссылки на скрипт ... это не имеет ничего общего с программированием.
Йриста
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». Затем я запустил «помощь для», чтобы понять, что он делает. Очевидно, прошло много времени с тех пор, как я смотрел на сценарии командной строки, потому что я понятия не имел, что команда «for» имеет так много опций.
Seanmc
Нет проблем! Во время тестирования я также использовал «echo» =) Чтобы увидеть больше вывода, удалите «2> nul». Я хотел сделать что-то подобное для моих собственных файлов NEF / JPG, и это была прекрасная возможность.
Anon
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
Просто к сведению: кажется, что это не работает, когда файлы действительно названы .jPg. Он также не работает, когда файлы находятся на внешнем диске и в каталоге отходов, например, в /homedir.
Therealmarv
некоторые исправления: gist.github.com/therealmarv/ec603bd4a91d51092a18
therealmarv
@therealmarv: на самом деле, что происходит с ImageMagick, так это то, что скрипт открывается в оболочке, а не в ImageMagick, но «import» - это имя инструмента 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)
ttaveira
источник
5
  • Создать пустую библиотеку
  • В главном меню Lightroom выберите «Правка»> «Настройки» (Windows) или «Lightroom»> «Настройки» (Mac OS).
  • В общих настройках снимите флажок «Обрабатывать файлы JPEG рядом с необработанными файлами как отдельные фотографии»
    • Это должно быть по умолчанию.
  • Импортируйте все свои файлы (вы можете выбрать подпапки поиска), сообщая о том, что нужно переместиться в другое место
  • Файлы JPG, содержащие файлы RAW, будут оставлены в исходном месте, чтобы вы могли их удалить.

Насколько я понимаю, миниатюра в lightroom может содержать RAW + JPG, но JPG на самом деле не хранится и не доступен каким-либо образом.

Вы также можете написать довольно простой пакетный скрипт на любом языке программирования.

Eruditass
источник
2

Мне нравится bash-скрипт для OS X (автор T.Toivonen ), но я заметил, что есть несколько проблем.

  • Мне не понравились мои имена каталогов, которые содержат пробелы. Это потребовало немного другой обработки команды 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 (и я планирую лучше посмотреть на этот ответ, когда я нахожусь на рабочем столе, чтобы немного изменить поведение)
Крис Х,
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, чтобы получить bash на 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
BSOD
источник
1

Вот мое мнение по этому вопросу. Много хороших идей пришли из более ранних сценариев, упомянутых здесь.

Это Баш скрипт для OS X . Он ищет файлы, которые существуют с тем же базовым именем файла и dng+jpgрасширениями. Если jpgнайден файл с точно таким же именем, как 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 . По сравнению со сценарием ттавейры он выполняет дополнительную работу.

  • Смотрит в подкаталоги.
  • Создает целевой каталог отходов.
  • Удаляет файлы, которые уже существуют в каталоге отходов, чтобы избежать ошибок перемещения.

# 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. Чем ваш ответ отличается от ответа ттавейры ?
Saaru Lindestøkke
Скрипт выполняет дополнительную работу: также просматривает все подкаталоги, создает целевой каталог отходов для jpg, если он не существует, и удаляет jpg вместо перемещения, если он уже существует в каталоге отходов (избегая ошибок перемещения)
Томи
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
Андре Парейс
источник