EXIF डेटा को देखते हुए, मैं फ़ोटो का नाम कैसे बदल सकता हूँ?


14

मान लें कि मेरे पास फ़ोटो का एक गुच्छा है, सभी सही EXIF ​​जानकारी के साथ हैं, और फ़ोटो को बेतरतीब ढंग से नाम दिया गया है (एक समस्या के कारण)। मेरा एक छोटा सा कार्यक्रम है, jheadजो मुझे निम्न आउटपुट देता है:

$ jhead IMG_9563.JPG

File name    : IMG_9563.JPG
File size    : 638908 bytes
File date    : 2011:02:03 20:25:09
Camera make  : Canon
Camera model : Canon PowerShot SX210 IS
Date/Time    : 2011:02:03 20:20:24
Resolution   : 1500 x 2000
Flash used   : Yes (manual)
Focal length :  5.0mm  (35mm equivalent: 29mm)
CCD width    : 6.17mm
Exposure time: 0.0080 s  (1/125)
Aperture     : f/3.1
Focus dist.  : 0.29m
ISO equiv.   : 125
Exposure bias: -1.67
Whitebalance : Manual
Light Source : Daylight
Metering Mode: pattern
Exposure Mode: Manual

अब मुझे अगले प्रारूप में फ़ोल्डर में सभी फ़ोटो का नाम बदलने की आवश्यकता है:

001.JPG
002.JPG
003.JPG
...

जहां छोटी संख्या में पुरानी छवि होगी, और अधिकतम नया होगा।

मैं इतनी अच्छी स्क्रिप्टिंग नहीं कर रहा हूं, इसलिए मैं मदद मांग रहा हूं।

मुझे लगता है कि एक बैश स्क्रिप्ट पर्याप्त है, लेकिन यदि आप अधिक सहज महसूस करते हैं, तो आप एक पायथन स्क्रिप्ट लिख सकते हैं।

मैंने कुछ इस तरह से सोचा:

$ mv IMG_9563.JPG `jhead IMG_9563.JPG | grep date`

लेकिन मैं नहीं जानता कि कैसे एक ही बार में सभी फ़ाइलों के लिए।


मैं मामूली / अधिकतम वाक्य और पूर्ववर्ती उदाहरण को नहीं समझता। क्या आप इसे स्पष्ट कर सकते हैं?
मैक्सक्लेपज़िग

वह मामूली / अधिकतम फ़ाइल नाम एक कदम ऊपर है। क्योंकि, एक बार जब मेरे पास एक तरह से नाम वाली फाइलें होती हैं जो उनका प्रतिनिधित्व करती हैं जो पुरानी और नई हैं, तो मैं आसानी से किसी अन्य प्रोग्राम के साथ 001.jpg, 002.jpg, आदि का नाम बदल सकता हूं, हालांकि यह बेहतर होगा कि इसे किसी अन्य स्क्रिप्ट के साथ किया जाए।
टॉमस

"नामकरण तालिका" होगी ls *.JPG | wc > renameऔर फिर मुझे एक स्क्रिप्ट का नाम बदलकर XXX.JPG
टॉमस

सॉरी, नहीं है wc, मैं नाम से ऑर्डर करने के लिए भूल गया।
टॉमस

कमांड सॉर्ट है।
टॉमस

जवाबों:


10

आप लूप (शेल / स्क्रिप्ट में) के लिए लूप का उपयोग करके सभी फ़ाइलों के लिए कर सकते हैं:

for i in *.JPG; do
  j=`jhead "$i" | grep date | sed 's/^File date[^:]\+: \(.\+\)$/\1/'`.jpg
  echo mv -i "$i" "$j"
done

यह सिर्फ एक बहुत ही मूल रूपरेखा है। echoजब आपने सत्यापित किया है कि सब कुछ उम्मीद के अनुसार काम करता है, तो हटाएं ।


धन्यवाद। अब, grep woudl मुझे दे File date : 2011:02:03 20:25:09। मैं केवल दूसरे कॉलम को कैसे फ़िल्टर कर सकता हूं?
टॉमा

इसलिए मैं केवल फ़ाइल का नाम बदलकर 20:25:09
टॉमस

@ टॉमास ने उत्तर को अपडेट किया - यदि आप वास्तव में केवल समय चाहते हैं (तब टकरावों के बारे में क्या है?) आपको नियमित अभिव्यक्ति को संशोधित करना होगा, निश्चित रूप से।
मैक्सक्लेपज़िग

j=`jhead "$i" | grep date | sed 's/.* //'`.jpgबजाय?
frabjous

@ maxshlepzig: धन्यवाद, आप '`` .jpg 'से पहले चूक गए थे
टॉमस

29

बस यहाँ पता चला है कि jhead आप के लिए यह सब कर सकते हैं! :)

jhead -autorot -nf%Y-%m-%d_%H-%M-%S *.jpg

7
हाँ! लेकिन उस विशेष प्रारूप-स्ट्रिंग से सावधान रहें, क्योंकि यह एक ही नाम में दो फ़ाइलों को एक ही नाम देगा। %i(या %03i, विशेष रूप से) एक अनुक्रम संख्या देगा, जैसा कि मूल प्रश्न में अनुरोध किया गया है। दोनों का मेल एक बुरा विचार नहीं हो सकता है।
Mattdm

बस मैटमैट की टिप्पणी का जवाब देने के लिए - '' jhead '' मैनुअल से पता चलता है कि यह एक अतिरिक्त संख्या या अक्षर (1,2,3 या a, b, c आदि) को स्वचालित रूप से डुप्लिकेट (समान टाइमस्टैम्प) में जोड़ देगा।
जॉन यू

0

अगर किसी को अधिक जटिल नाम बदलने की आवश्यकता है, उदाहरण के लिए फ़ाइल नाम में प्रमुख एक्सपोज़र मान शामिल करने के लिए, यहां मेरी छोटी स्क्रिप्ट है। यह jpeg फ़ाइलों को कुछ इस तरह से नाम देता है NightSky_2014.08.27_22.30.05_NX20_F2.8_f20.0mm_20s_ISO800.jpg:।

#!/bin/bash

for s in *.jpg *.JPG
do
 echo $s
 x=`jhead "$s" | \
 awk 'BEGIN { cmt=""; }
/Camera model/   { c=$4$5$6;} 
/Exposure time:/ { e=$3; 
                   if (e==int(e)) e=int(e); 
                   if (e<1) {e=int(0.5+1/e); e="1T" e "s";} else { e=e "s"; } 
                 }
/ISO equiv./     { iso="ISO" $4; } 
/Focal length/   { f="f" $4; } 
/Date.Time /     { d=$3 "_" $4; gsub(":",".",d); }
/Aperture /      { ap=$3; gsub("f/","F",ap); } 
/Comment  /      { cmt=$3 "_"; }
END { print cmt d "_" c "_" ap "_" f "_" e "_" iso ".jpg"; }'`

 echo mv $s $x
 mv $s $x
 echo =====
done

0

मुझे maxschlepzig द्वारा पोस्ट किया गया कोड पसंद आया लेकिन फिर भी आउटपुट के साथ कठिनाइयाँ थीं।

समस्या परिणामी फ़ाइल नाम (दिनांक स्ट्रिंग और समय स्ट्रिंग के बीच) में जगह थी। जीयूआई का उपयोग करने वाले किसी भी व्यक्ति के लिए तुच्छ होने पर, यह कमांड-लाइन पर फ़ाइल हैंडलिंग को कुछ अधिक कठिन बना देता है।

यहां 'सेड' कमांड को पिछले मोनोलिथिक तर्क के पक्ष में चार अलग-अलग 'सेड' ऑपरेशनों में काफी हद तक बदल दिया गया है। अपने आप को सूट करने के लिए, फ़ाइल सामान्य 644 अनुमतियों के लिए फ़ाइल भी बदलती है।

for i in *.JPG ; do
  chmod 644 $i
  j=`jhead "$i" | grep ^Date/Time | sed -e 's/^Date\/Time[ ]\+: //;s/:/-/g;s/ /_/g':/-/g;s/ /_/g'`.jpg
  echo mv -i "$i" "$j"
  # mv -i "$i" "$j"
done

2
स्टैक एक्सचेंज में आपका स्वागत है। (1) मैं sedअच्छी तरह से समझता हूं, इसलिए मैं मूल रूप से समझता हूं कि आप क्या करने की कोशिश कर रहे हैं। लेकिन स्टैक एक्सचेंज में हमारा लक्ष्य मछली सैंडविच को सौंपना या तुच्छ अलग-अलग प्रश्नों के हजारों एक-बंद समाधान लिखना नहीं है; हमारा लक्ष्य लोगों को मछली कैसे सिखाना है (यानी, लोगों को सिखाना, वर्तमान प्रश्नकर्ता और भविष्य के पाठकों सहित, अपनी समस्याओं को कैसे हल करना है)। उस अंत तक, आपका उत्तर बेहतर होगा यदि आपने समझाया कि आप क्या प्रयास कर रहे हैं। (कृपया टिप्पणियों में प्रतिक्रिया न दें । इसे स्पष्ट करने के लिए अपने उत्तर को संपादित करें।) ... (Cont'd)
जी-मैन कहते हैं 'मोनिका की बहाली'

(Cont'd)… (2) आपका आदेश विफल हो जाता है क्योंकि उद्धरण संतुलित नहीं हैं। कृपया बिना कोड के पोस्ट न करें।
जी-मैन का कहना है कि 'मोनिका' को पुनः स्थापित करें

0

क्योंकि (imho) से निपटना आसान है, मैंने खुद को रूबी स्क्रिप्ट लिखा है:

require 'fileutils'

ARGV.each { |file|
  if File.exist?(file) && !File.directory?(file)
    exif = `exiftool "#{file}" | grep -E "(Error|Create Date)"`
    if exif.strip.size > 0
      exif = exif.split("\n")[0].split(/\s+/)
      if exif[0] != "Error"
        # Change the target format here
        filename = exif[3].gsub(":", "-") + " " + 
                   exif[4].gsub(":", ".") + 
                   File.extname(file)
        if filename != file && !File.exist?(filename)
          FileUtils::mv(file, File.dirname(file) + "/" + filename)
        end
      end
    end
  end
}

यह क्या करता है?

  1. पैरामीटर (जैसे *.JPG) के रूप में पारित सभी फाइलों पर Iterates ।

    मैंने जाँच की कि यह रॉ फाइलों और वीडियो को सही ढंग से हैंडल करता है। यह सब कुछ के साथ काम exiftoolकर सकते हैं के साथ काम करना चाहिए ।

  2. अगर कोई फ़ाइल कुछ नहीं करता है

    • अस्तित्व में नहीं है,
    • एक निर्देशिका है,
    • एक EXIF ​​दिनांक नहीं है, या
    • exiftool त्रुटि की रिपोर्ट करता है, या
    • लक्ष्य फ़ाइल नाम वाली फ़ाइल पहले से मौजूद है।

जो इसे काफी मजबूत बनाता है। विशेष रूप से, कोई भी फाइल गायब नहीं हो सकती (चुपचाप) जैसा कि कुछ अन्य उत्तरों के साथ होता है।


0

exiv2 हेरफेर के लिए एक विकल्प होगा, जो एक बहुत ही सरल वाक्यविन्यास की अनुमति देता है:

exiv2, Exif, IPTC, XMP मेटाडेटा और छवि टिप्पणियों को पढ़ने और लिखने का एक कार्यक्रम है और कई विक्रेता मेकओवर टैग पढ़ सकते हैं। प्रोग्राम वैकल्पिक रूप से Exif टैग, XMP गुण और IPTC डेटासेट के बीच शंकु क्रिया करता है

तो यह मौजूदा फ़ोल्डर में सभी jpegs का नाम बदल देगा:

for i in *.JPG; do exiv2 -v -r '%Y%m%d.%H%M%S.:basename:' rename "$i"; done

यदि आप भी भू सूचना जोड़ना चाहते हैं, तो आप उपयोग कर सकते हैं exivtool:

exiftool '-filename<${gpslatitude;} ${gpslongitude} ${datetimeoriginal}' -d "%Y-%m-%d %H.%M.%S%%-c.%%e" *.JPG

0

मुझे @ केविन का समाधान पसंद है, क्योंकि मैं मूल नाम भी रखना चाहता था (उसी सेकंड में ली गई छवियों से समस्या से बचना), यहाँ यह मेरा समाधान है:

for i in *.JPG; do jhead -nf%Y%m%d_%H%M%S_"$(basename "$i" .JPG)" "$i" ; done

0

नौसिखिया द्वारा पहली पोस्टिंग ... पहली बैश स्क्रिप्ट ... मुझे लिबोर / हालोसगहोस्ट समाधान ऊपर पसंद आया क्योंकि इसमें नाम में अधिक विवरण शामिल थे। लेकिन परीक्षण के बाद, डुप्लिकेट फ़ाइल नाम फ़ाइलों को खोने का अंत करेंगे। इसलिए मैंने आसान संदर्भ और टक्कर की रोकथाम के लिए फ़ाइल नाम के अंत में एक काउंटर टैग जोड़ा। मुझे यकीन है कि यहां कोई व्यक्ति इस पर सुधार कर सकता है लेकिन सोचा कि इससे मदद मिल सकती है।

कोड पोस्ट करते हुए मेरी माफ़ी। मुझे इंटरफ़ेस में कठिनाइयाँ हो रही हैं, लेकिन अगर कोई मुझे चीजों को करने के सही तरीके की ओर इशारा कर सकता है, तो यह बहुत अच्छा होगा।

#!/bin/bash

y=1
for s in *.jpg *.JPG
do
 echo $s
 x=`jhead "$s" | \
 awk 'BEGIN { cmt=""; }
/Camera model/   { c=$4$5$6;}
/Exposure time:/ { e=$3;
                   if (e==int(e)) e=int(e);
                   if (e<1) {e=int(0.5+1/e); e="1T" e "s";} else { e=e "s"; }
                 }
/ISO equiv./     { iso="ISO" $4; }
/Focal length/   { f="f" $4; }
/Date.Time /     { d=$3 "_" $4; gsub(":","",d); }
/Aperture /      { ap=$3; gsub("f/","F",ap); }
/Comment  /      { cmt=$3 "_"; }
END { print cmt d "_" c "_" ap "_" f "_" e "_" iso "_" ; }'`

 echo mv $s "$x${y}.jpg"
 mv $s "$x${y}.jpg"
 y=$((y+1))
 echo =====
done

संपादित करने के लिए धन्यवाद स्टीफन। सीखने की कोशिश कर रहा है
jgroezin
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.