Come eliminare i file JPG, ma solo se esiste il file RAW corrispondente?


18

Le mie prime foto (Canon G2) sono tutte in formato JPG, ma quando ho ottenuto la mia Nikon D90 ho scattato inizialmente in JPG, poi sono passato a RAW + JPG e ora vorrei passare solo a RAW.

Ho letteralmente migliaia di foto sul mio HDD. Le foto si trovano in sottodirectory (per data) in un'unica directory denominata Importa.

Sto per importare tutte queste foto in Lightroom 3.0, tuttavia, vorrei eliminare tutti i file JPG, ma solo dove esiste già un file RAW corrispondente (ovvero non voglio più conservare le versioni JPG e RAW degli stessi file).

Se riesco a farlo facilmente in Lightroom (dopo aver importato tutto, inclusi i file JPG duplicati), sarebbe fantastico. Sarebbe anche OK se ci fosse un modo semplice per farlo prima di importare i file (ma speriamo che ciò non implichi la necessità di visitare tutte le directory alla ricerca di nomi di file con estensione JPG e NEF).

Qualcuno conosce un modo per farlo (in Lightroom o con alcuni strumenti / script in Windows)?


Tutti i tuoi file jpg e RAW hanno almeno la stessa stringa (è possibile aggiungere altri caratteri a entrambi)? Ad esempio IMG_1234_portrait_picture.jpg & IMG_1234.CR2.
dpollitt,

Penso che tutte le mie coppie JPG / NEF abbiano esattamente lo stesso nome file (tranne l'estensione).
seanmc,

3
Voterò a spostare questo a Stack Overflow, dove si dovrebbe ottenere una risposta in pochi minuti =)
anon

1
@anon: In che modo appartiene esattamente a StackOverflow? Questa è sicuramente una domanda sull'argomento, in quanto si tratta di strumenti per la gestione delle immagini e il fotoritocco. Al di fuori di un riferimento tangenziale allo script ... questo non ha nulla a che fare con la programmazione.
jrista

2
Sto votando per chiudere questa domanda come fuori tema perché non si tratta in realtà di fotografia, si tratta di gestire i file che sono solo fotografie. La domanda e la risposta sarebbero le stesse se i due tipi di file in questione fossero altri tipi di file che possono essere tradotti da una forma all'altra, come file .doc e .pdf, ecc.
xiota

Risposte:


24

Su Windows , vai alla cartella ed eseguilo nel prompt dei comandi:

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

Fondamentalmente, passa attraverso la cartella corrente, esegue i file NEF ed elimina JPG se presente. Ignora eventuali errori se il JPG non è presente.

Se si desidera una sottocartella, includere /snel dircomando.


3
Perfetto grazie! Naturalmente prima di eseguirlo la prima volta, ho cambiato "del" in "eco". Quindi ho eseguito "aiuto per" per capire cosa stava facendo. Ovviamente è passato molto tempo da quando ho esaminato gli script del prompt dei comandi, perché non avevo idea che il comando "for" avesse così tante opzioni.
seanmc,

Nessun problema! Mentre stavo testando, ho anche usato "echo" =) Per vedere più output, rimuovi "2> nul". Avevo intenzione di fare qualcosa del genere per i miei file NEF / JPG, e questa era l'occasione perfetta.
anon

7

Ecco una versione modificata dello script Python di Tomy . differenze:

  • sono consentite più estensioni non elaborate
  • rimuovi jpg solo se le coppie si trovano nella stessa cartella (evita la rimozione accidentale di un jpg chiamato come un file raw in un'altra cartella)
  • senza distinzione tra maiuscole e minuscole

#!/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)

ottima sceneggiatura. Lo userò perché ha molti buoni failover. Tuttavia, dovresti aggiungere questa riga #!/usr/bin/env pythonall'inizio. Altrimenti ho avuto strani errori di ImageMagick (sembra che il mio mac apra file .py con ImageMagick)
therealmarv

Cordiali saluti: sembra anche che non funzioni quando i file sono realmente denominati .jPg. Inoltre non funziona quando i file si trovano su un disco esterno e nella directory di spreco, ad es /home. In dir.
therealmarv,


@therealmarv: in realtà ciò che sta accadendo con ImageMagick è che lo script viene aperto nella shell, non ImageMagick, ma "import" è il nome di uno strumento ImageMagick.
Max

6

Ecco uno script Python che sposta i JPGfile quando non RAWesiste alcun file corrispondente . Utile su 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
  • Crea una libreria vuota
  • Dal menu principale di Lightroom, scegliete Modifica> Preferenze (Windows) o Lightroom> Preferenze (Mac OS).
  • Nelle preferenze generali deseleziona "Tratta i file JPEG accanto ai file non elaborati come foto separate"
    • Questo dovrebbe essere il valore predefinito.
  • Importa tutti i tuoi file (puoi selezionare le sottocartelle di ricerca), dicendogli di spostarsi in una nuova posizione
  • I file JPG che hanno file RAW verranno lasciati nella posizione originale per poter essere rimossi

A quanto ho capito, la miniatura in Lightroom potrebbe dire RAW + JPG, ma il JPG non è effettivamente memorizzato o accessibile in alcun modo.

Puoi anche scrivere uno script batch piuttosto semplice con qualsiasi linguaggio di programmazione.


2

Mi piace lo script bash per OS X (di T.Toivonen ), ma ho notato che ci sono alcuni problemi.

  • Non mi sono piaciuti i nomi delle mie directory, che contengono spazi. Ciò ha richiesto una gestione leggermente diversa del comando find.

  • Lo script originale funziona solo con estensioni minuscole. Ho leggermente migliorato quella parte dello script per tenere conto anche delle estensioni in maiuscolo. Nota che accetta solo DNG+JPGo dng+jpgaccoppia e ignorerà qualsiasi combinazione come DNG+jpgo DnG+JpG.

  • La soluzione originale ha proposto solo una wastedirposizione, mentre la mia correzione consente di creare una sottodirectory su ogni ramo della directory mentre viaggia. Si definisce un nome della directory prima del ciclo.

  • Mi piace vedere cosa sta succedendo, soprattutto quando mvo rmsi utilizzano i comandi;)

Per motivi di spazio, sto mostrando solo l'ultima parte dello script, dall'impostazione di a basedir, wastedire il ciclo.

[...]

#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

La domanda è stata taggata "Windows" in modo da poter dire dicendo come farlo funzionare in un tipico sistema Windows. Eseguo Cygwin, ad esempio (e ho intenzione di dare un'occhiata migliore a questa risposta quando sono sul desktop, per cambiare un po 'il comportamento)
Chris H

2

Ecco una soluzione per bash(Linux o Mac OS X). Su Windows, è possibile installare Cygwin per ottenere una copia di 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

Ecco un'altra bashversione che utilizza find(Linux). Come con la risposta di Ben Pingilley , puoi installare Cygwin per ottenere bash su 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

1

Ecco la mia opinione su questo problema. Molte buone idee sono nate da script precedenti menzionati qui.

Si tratta di uno script bash per OS X . Cerca i file che esistono con lo stesso nome file ed dng+jpgestensioni di base . Se jpgsi trova a con esattamente lo stesso nome di dng, allora quel nome file viene visualizzato ( -e), il file viene spostato ( -m) o eliminato ( -d).

Passerà attraverso le sottocartelle, quindi è possibile utilizzarlo per l'intero catalogo o solo parti di esso.

Per altre estensioni di file non elaborate basta sostituire *.dnglo script con l'estensione preferita.

Avvertenza: potresti avere due immagini diverse con lo stesso nome, ma con un'estensione diversa. Quelle sono inevitabili vittime di questa sceneggiatura.

Ecco come utilizzare lo script:

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 

L'utilizzo di base funzionerebbe in questo modo:

$ ./dng-jpg.sh -e /Volumes/photo/DNG/2015

Ciò farebbe eco a tutti i nomi di jpgfile dei file che corrispondono ai criteri di avere entrambi dnge jpgfile con lo stesso nome.

Il risultato sarebbe simile a questo:

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.

Ora, se voglio eliminare i file, vorrei semplicemente passare -ea -d:

$ ./dng-jpg.sh -d /Volumes/photo/DNG/2015

O se mi piacerebbe spostare i file in / duplicati con cui eseguirlo -m.

$ ./dng-jpg.sh -m /Volumes/photo/DNG/2015

Ora i jpgfile duplicati sarebbero presenti/Volumes/photo/DNG/2015/duplicates

Ecco lo script: 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

Ecco un bashcopione per Mac OS X . Si può lavorare su Linux con alcune modifiche.

#!/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è un'utilità che sposta i file nel Cestino, invece di eliminarli completamente. Puoi scaricarlo da MacPorts in questo modo:

sudo port install rmtrash

Se vuoi evitarlo, sostituiscilo rmtrashnello script con rm, che eliminerà immediatamente i JPGfile.


1

Ho scritto il seguente script Python . Rispetto alla sceneggiatura di ttaveira , fa un lavoro extra.

  • Cerca nelle sottodirectory.
  • Crea directory di destinazione rifiuti.
  • Rimuove i file che già esistono nella directory dei rifiuti per evitare errori di spostamento.

# 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
Ciao e benvenuto su Photo.SE. In che modo la tua risposta è diversa dalla risposta di Ttaveira ?
Saaru Lindestøkke,

Lo script fa un po 'di lavoro extra: cerca anche in tutte le sottodirectory, crea la directory di spreco di destinazione per jpg se non esiste e rimuove un jpg invece di spostarlo se esiste già nella directory di spreco (evita errori di spostamento)
Tomy,

0

Lavorando su Mac OS X , nelle risposte precedenti mancava un controllo di integrità per lo "stesso contenuto". Avevo nomi duplicati per diverse immagini perché avevo dimenticato di abilitare il contatore di immagini nella mia fotocamera. Ecco la mia versione, che controlla le informazioni EXIF ​​per lo stesso tempo di acquisizione:

Devi correre

sudo port install rmtrash exiv2

prima di poter usare il seguente comando. È stato scritto per il confronto JPGcon i NEFfile della mia Nikon D90. Regola le estensioni dei file in base alle tue esigenze.

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

senza il controllo della sanità mentale, l'intera faccenda sarebbe diventata molto breve:

find . -name \*.NEF |sed s/\.NEF/.JPG/g | xargs find 2>/dev/null | xargs rmtrash
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.