일치하는 RAW 파일이 존재하는 경우에만 JPG 파일을 삭제하는 방법은 무엇입니까?


18

초기 (Canon G2) 사진은 모두 JPG이지만 Nikon D90을 처음 가져 왔을 때 JPG로 촬영 한 다음 RAW + JPG로 전환했습니다. 이제 RAW로만 전환하고 싶습니다.

HDD에 문자 그대로 수천 장의 사진이 있습니다. 사진은 가져 오기라는 단일 디렉토리 아래의 하위 디렉토리 (날짜 별)에 있습니다.

이 모든 사진을 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 : 이것이 정확히 어떻게 OverOverflow에 속합니까? 이것은 이미지 관리 및 사진 편집 도구를 다루기 때문에 가장 확실한 주제입니다. 스크립트에 대한 접선 참조 외에는 ... 이것은 프로그래밍과 관련이 없습니다.
jrista

2
나는이 질문을 주제에 맞지 않기로 투표하고 있습니다. 왜냐하면 이것이 실제로 사진에 관한 것이 아니라 단지 사진 인 파일을 관리하는 것입니다. 문제의 두 유형의 파일이 .doc 및 .pdf 파일과 같이 한 형식에서 다른 형식으로 변환 될 수있는 다른 유형의 파일 인 경우 질문과 대답은 동일합니다.
xiota

답변:


24

윈도우 폴더로 이동 프롬프트 명령이 실행 :

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의 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 오류가 발생했습니다 (ImageMagick과 함께 내 Mac에서 열린 .py 파일을
간주 함

참고로 파일 이름이 실제로 지정되면 작동하지 않는 것 같습니다 .jPg. 또한 파일이 외부 디스크에 있고 폐기물 디렉토리 (예 : /homedir) 에 있으면 작동하지 않습니다 .
therealmarv


@therealmarv : 실제로 ImageMagick에서 일어나는 일은 스크립트가 ImageMagick이 아니라 셸에서 열리고 있지만 "import"는 ImageMagick 도구의 이름입니다.
최대

6

해당 파일이 없을 때 파일 을 이동 시키는 Python 스크립트 는 다음과 같습니다 . Mac OS X 에서 유용합니다 !JPGRAW

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 파일은 제거 할 수 있도록 원래 위치에 남아 있습니다.

알다시피, 라이트 룸의 썸네일은 RAW + JPG로 표시 될 수 있지만 JPG는 실제로 저장되거나 액세스 할 수 없습니다.

모든 프로그래밍 언어로 매우 간단한 배치 스크립트를 작성할 수도 있습니다.


2

나는 OS X 용 bash 스크립트 ( T.Toivonen )를 좋아하지만 몇 가지 문제가 있음을 알았습니다.

  • 공백이 포함 된 내 디렉토리 이름이 마음에 들지 않았습니다. 찾기 명령을 약간 다르게 처리해야했습니다.

  • 원본 스크립트는 소문자 확장자에만 작동합니다. 대문자로 된 확장명을 설명하기 위해 스크립트의 해당 부분을 약간 개선했습니다. 그것은 단지 받아들이는, 주 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

(Linux)를 bash사용하는 다른 버전이 find있습니다. 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 X 용 bash 스크립트입니다 . 기본 파일 이름과 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을 모두 갖는 기준과 일치하는 파일의 모든 파일 이름을 에코합니다 .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

다음 파이썬 스크립트를 작성했습니다 . ttaveira의 script 와 비교하면 추가 작업이 필요합니다.

  • 하위 디렉토리를 찾습니다.
  • 대상 폐기물 디렉터리를 만듭니다.
  • 이동 오류를 피하기 위해 낭비 디렉토리에 이미 존재하는 파일을 제거합니다.

# 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에 대한 대상 폐기물 디렉토리를 생성하고, 낭비 디렉토리에 이미 존재하는 경우 jpg를 이동하는 대신 jpg를 제거합니다 (이동 오류 방지)
Tomy

0

Mac OS X 에서 작업 하면서 이전 답변에서 "같은 내용"에 대한 위생 검사가 누락되었습니다. 카메라에서 이미지 카운터를 활성화하는 것을 잊었 기 때문에 다른 사진의 이름이 중복되었습니다. 동일한 캡처 시간에 대한 EXIF ​​정보를 확인하는 내 버전은 다음과 같습니다.

당신은 실행해야합니다

sudo port install rmtrash exiv2

다음 명령을 사용하기 전에. 내 Nikon D90의 파일 JPG과 비교하기 위해 작성되었습니다 NEF. 필요에 따라 파일 확장자를 조정하십시오.

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.