Все мои ранние (Canon G2) фотографии были в формате JPG, но когда я получил свой Nikon D90, я сначала снимал в формате JPG, затем переключился на RAW+JPG, а теперь хочу переключиться только на RAW.
У меня буквально тысячи фотографий на жестком диске. Фотографии находятся в подкаталогах (по дате) в одном каталоге под названием «Импорт».
Я собираюсь импортировать все эти фотографии в Lightroom 3.0, однако я хотел бы удалить все файлы JPG, но только там, где уже есть соответствующий файл RAW (т.е. я больше не хочу хранить версии JPG и RAW одного и того же файл).
Если бы я мог легко сделать это в Lightroom (после импорта всего, включая дубликаты файлов JPG), это было бы здорово. Также было бы хорошо, если бы был простой способ сделать это перед импортом файлов (но, надеюсь, это не потребовало бы посещения каждого каталога в поисках имен файлов с расширениями JPG и NEF).
Кто-нибудь знает, как это сделать (в Lightroom или с помощью какого-либо инструмента/скрипта в Windows)?
В Windows перейдите в папку и запустите в командной строке:
for /f "delims==" %r in ('dir /b *.nef') do del "%~dpr%~nr.jpg" 2> nul
По сути, он проходит через текущую папку, просматривает файлы NEF и удаляет JPG, если он есть. Он игнорирует любые ошибки, если JPG отсутствует.
Если вам нужны подпапки, включите /s
в dir
команду.
Вот модифицированная версия Python-скрипта Tomy . Отличия:
#!/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).jPg
. Это также не работает, когда файлы находятся на внешнем диске и в ненужном каталоге, например, в каталоге /home
.Вот скрипт 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)
Насколько я понимаю, на миниатюре в лайтруме может быть написано RAW+JPG, но на самом деле JPG не хранится и не доступен каким-либо образом.
Вы также можете написать довольно простой пакетный скрипт на любом языке программирования.
Мне нравится сценарий bash для OS X (от T.Toivonen ), но я заметил несколько проблем.
Ему не нравились мои имена каталогов, содержащие пробелы. Это потребовало немного другой обработки команды find.
Оригинальный скрипт работает только для расширений нижнего регистра. Я немного улучшил эту часть скрипта, чтобы учесть расширения, которые также пишутся в верхнем регистре. Обратите внимание, что он принимает только пары DNG+JPG
или dng+jpg
и игнорирует любые комбинации, такие как DNG+jpg
или DnG+JpG
.
Первоначальное решение предлагало только одно wastedir
местоположение, тогда как мое исправление позволяет создавать подкаталог в каждой ветке каталога по мере его перемещения. Вы определяете имя каталога перед циклом.
Мне нравится видеть, что происходит, особенно когда используются команды mv
или rm
;)
Для экономии места я показываю только последнюю часть скрипта, начиная с установки a 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
Вот решение для 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
Вот еще одна 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
Вот мой взгляд на этот вопрос. Много хороших идей пришло из более ранних сценариев, упомянутых здесь.
Это 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
Или, если я хочу переместить файлы в /duplicates, я бы выполнил это с расширением -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."
Вот 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
файлы.
Я написал следующий скрипт 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)
Работая над 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
дполлитт
ШонМк
скоро
джриста
скоро
Роуленд Шоу
скоро
матдм
ШонМк
ксиота