仅当匹配的RAW文件存在时,如何删除JPG文件?


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 2011年

我认为我所有的JPG / NEF对都具有完全相同的文件名(扩展名除外)。
seanmc 2011年

3
我将投票给这个移动到堆栈溢出,你应该得到分钟内回答=)
匿名

1
@anon:这到底属于StackOverflow吗?这绝对是这里的热门话题,因为它涉及图像管理和照片编辑工具。除了对脚本的切向引用之外,这与编程无关。
jrista

2
我投票结束这个问题是因为题外话,因为这实际上与摄影无关,而是关于管理恰好是照片的文件。如果所讨论的两种类型的文件是可以从一种格式转换为另一种格式的任何其他类型的文件,例如.doc和.pdf文件,则问题和答案将是相同的
。– xiota,

Answers:


24

Windows上,转到文件夹,然后在命令提示符下运行此文件夹:

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

基本上,它将遍历当前文件夹,遍历NEF文件,并删除JPG(如果存在)。如果没有JPG,它将忽略任何错误。

如果需要子文件夹,请/sdir命令中包含。


3
很好,谢谢!当然,在我第一次运行它之前,我将“ del”更改为“ echo”。然后我运行“帮助”以了解它在做什么。自从我查看命令提示符脚本以来,显然已经过去了很长时间,因为我不知道“ for”命令有这么多的选择。
seanmc 2011年

没问题!在测试时,我还使用了“ echo” =)要查看更多输出,请删除“ 2> nul”。我一直想对自己的NEF / JPG文件执行类似的操作,这是绝佳的机会。
匿名

7

这是Tomy 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用ImageMagick打开了.py文件)
therealmarv 2015年

仅供参考:当文件真正命名时,它似乎也不起作用.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文件处理为单独的照片”
    • 这应该是默认值。
  • 导入所有文件(您可以选择搜索子文件夹),并告诉它移至新位置
  • 具有RAW文件的JPG文件将保留在原始位置,以供您删除

据我了解,lightroom中的缩略图可能显示RAW + JPG,但实际上JPG并未以任何方式存储或访问。

您还可以使用任何编程语言编写一个非常简单的批处理脚本。


2

我喜欢OS Xbash脚本(由T.Toivonen撰写),但是我注意到有一些问题。

  • 它不喜欢我的目录名称,其中包含空格。这需要对find命令进行一些不同的处理。

  • 原始脚本仅适用于小写扩展名。我对脚本的这一部分进行了一些改进,以解决大写扩展的问题。请注意,它仅接受DNG+JPGdng+jpg配对,并且将忽略任何组合,例如DNG+jpgDnG+JpG

  • 原始解决方案仅提出了一个wastedir位置,而我的修正允许在旅行时在每个目录分支上创建一个子目录。您可以在循环之前定义目录的名称。

  • 我喜欢看看发生了什么,特别是当使用mvrm命令时;)

因为我只显示脚本的最后一部分,从设置空间的缘故basedirwastedir和循环。

[...]

#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)的另一个版本。与Ben Pingilley的答案一样,您可以安装Cygwin在Windows上获取bash。

#!/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 Xbash脚本。它查找具有相同基本文件名和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显符合具有dngjpg具有相同名称的文件的条件的文件的所有文件名。

结果看起来像这样:

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."

1

这是Mac OS Xbash脚本。进行一些更改后,它就可以在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的答案有何不同?
SaaruLindestøkke2014年

该脚本做了一些额外的工作:还查找所有子目录,如果不存在jpg,则为jpg创建目的地废纸目录,如果废纸目录中已经存在jpg,则它将删除而不是移动jpg(避免移动错误)
Tomy

0

Mac OS X上工作时,我在前面的答案中缺少对“相同内容”的健全性检查。我为不同的图片使用了重复的名称,因为我忘记了在相机中启用图像计数器。这是我的版本,用于检查EXIF信息是否具有相同的捕获时间:

你需要跑步

sudo port install rmtrash exiv2

您可以使用以下命令。编写该文件是为了JPGNEF我的尼康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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.