Как удалить файлы JPG, но только если существует соответствующий файл RAW? - Фотопедия
18 голосов
/ 15 октября 2011

Все мои ранние фотографии (Canon G2) сделаны в формате JPG, но когда я получил свой Nikon D90, я изначально снимал в формате JPG, затем переключился на RAW + JPG, и теперь я хотел бы перейти только на RAW.

У меня буквально тысячи фотографий на моем жестком диске. Фотографии находятся в подкаталогах (по дате) в одном каталоге с именем Import.

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

Если бы я мог легко сделать это в Lightroom (после импорта всего, включая дубликаты файлов JPG), это было бы здорово. Также было бы хорошо, если бы существовал простой способ сделать это перед импортом файлов (но, надеюсь, это не потребовало бы посещения каждого каталога в поисках имен файлов с расширениями JPG и NEF).

Кто-нибудь знает, как это сделать (в Lightroom или с помощью какого-либо инструмента / скрипта в Windows)?

Ответы [ 11 ]

24 голосов
/ 15 октября 2011

В Windows , перейдите в папку и запустите ее в командной строке:

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

По сути, он проходит через текущую папку, проходит через файлы NEF и удаляет JPG, если он присутствует. Он игнорирует любые ошибки, если JPG там нет.

Если вы хотите подпапки, включите /s в команду dir.

7 голосов
/ 14 сентября 2014

Вот модифицированная версия скрипта 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)
6 голосов
/ 21 марта 2014

Вот 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 голосов
/ 15 октября 2011
  • Создать пустую библиотеку
  • В главном меню Lightroom выберите «Правка»> «Настройки» (Windows) или «Lightroom»> «Настройки» (Mac OS).
  • В общих настройках снимите флажок «Обрабатывать файлы JPEG рядом с необработанными файлами как отдельные фотографии»
    • Это должно быть по умолчанию.
  • Импортируйте все ваши файлы (вы можете выбрать подпапки поиска), указав переместить на новое место
  • JPG-файлы, содержащие RAW-файлы, останутся в исходном месте, чтобы вы могли их удалить

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

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

2 голосов
/ 09 апреля 2017

Мне нравится 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
2 голосов
/ 09 сентября 2015

Вот еще одна 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
2 голосов
/ 29 июня 2015

Вот решение для 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
1 голос
/ 05 января 2017

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

Это bash-скрипт для 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 голос
/ 23 апреля 2015

Вот скрипт 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 голос
/ 08 апреля 2014

Я написал следующий 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)
...