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

작은 숫자는 오래된 이미지이고 최대 이미지는 새로운 이미지입니다.

나는 스크립팅이 좋지 않아 도움을 요청하고 있습니다.

나는 bash 스크립트로 충분하다고 생각하지만 더 편안하다고 생각되면 파이썬 스크립트를 작성할 수 있습니다.

나는 다음과 같이 생각했다.

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

그러나 모든 파일에 대해 한 번에 그렇게하는 방법을 모르겠습니다.


부 / 최대 문장과 앞의 예를 이해하지 못합니다. 이것을 명확히 할 수 있습니까?
maxschlepzig

그 작은 / 최대 파일 이름은 한 단계입니다. 더 오래되고 더 새로운 파일을 나타내는 방식으로 이름이 지정된 파일이 있으면 다른 프로그램을 사용하여 001.jpg, 002.jpg 등으로 쉽게 이름을 바꿀 수 있지만 다른 스크립트를 사용하는 것이 더 좋습니다.
Tomas

"이름 바꾸기"는 ls *.JPG | wc > rename다음 스크립트 이름을 XXX.JPG로 사용해야합니다.
Tomas

Sory는 아닙니다 wc. 이름으로 주문하는 것을 잊었습니다.
Tomas

명령이 정렬됩니다.
Tomas

답변:


10

for 루프 (쉘 / 쉘 스크립트)를 사용하여 모든 파일에 적용 할 수 있습니다.

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. 두 번째 열만 필터링하려면 어떻게해야합니까?
Tomas

따라서 파일 이름 만 20:25:09로 변경
Tomas

@Tomas, 대답을 업데이트했습니다-실제로 시간 만 원한다면 (충돌은 어떻습니까?) 정규식을 수정해야합니다.
maxschlepzig

j=`jhead "$i" | grep date | sed 's/.* //'`.jpg대신?
frabjous

@maxshlepzig : 감사합니다, 당신이 놓친 '``전에 .jpg`
토마스

28

jhead가 당신을 위해 모든 것을 할 수 있다는 것을 여기서 발견했습니다 ! :)

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

7
예! 그러나 특정 형식 문자열에주의하십시오. 두 개의 파일을 같은 초에 동일한 이름으로 가져 오기 때문입니다. %i(또는 %03i구체적으로)은 원래 질문에서 요청한대로 시퀀스 번호를 제공합니다. 둘을 결합하는 것은 나쁜 생각이 아닙니다.
mattdm

mattdm의 의견에 응답하기 위해``jhead ''매뉴얼은 여분의 숫자 또는 문자 (1,2,3 또는 a, b, c 등)를 중복 (동일한 타임 스탬프)에 자동으로 추가 할 것을 제안합니다.
John U

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가 게시 한 코드를 좋아했지만 그럼에도 불구하고 출력에 어려움이있었습니다.

문제는 결과 파일 이름의 공백입니다 (날짜 문자열과 시간 문자열 사이). GUI를 사용하는 사람에게는 사소한 것이지만 명령 줄에서 파일 처리가 다소 어려워집니다.

여기서 'sed'명령은 이전의 모 놀리 식 논쟁에 찬성하여 4 개의 개별 'sed'연산으로 크게 변경되었습니다. 나 자신에게 적합하도록 다음은 파일을 일반 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
Stack Exchange에 오신 것을 환영합니다. (1) 나는 sed꽤 잘 이해 하므로 기본적으로 당신이하려는 일을 이해합니다. 그러나 Stack Exchange의 목표는 물고기 샌드위치를 ​​나눠 주거나 사소한 별개의 질문에 대해 수천 가지 일회성 솔루션을 작성하는 것이 아닙니다. 우리의 목표는 사람들에게 낚시하는 방법을 가르치는 것입니다 (즉, 현재의 질문자와 미래의 독자를 포함하여 사람들에게 자신의 문제를 해결하는 방법을 가르치는 것). 이를 위해 노력하고있는 것을 설명하면 대답이 더 나을 것입니다. (주석하지 응답을주세요 편집 답변을 그것을 명확하게 할 수 있습니다.) ... (계속)
G-남자 '분석 재개 모니카'말한다

(계속)… (2) 따옴표의 균형이 맞지 않아 명령이 실패합니다. 테스트되지 않은 코드는 게시하지 마십시오.
G-Man, 'Reinstate

0

(imho) 다루기가 더 쉽기 때문에 Ruby 스크립트를 작성했습니다.

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.

    RAW 파일 및 비디오를 올바르게 처리하는지 확인했습니다. 모든 것을 exiftool다룰 수 있어야합니다 .

  2. 파일 인 경우 아무것도하지 않습니다

    • 존재하지 않는다,
    • 디렉토리입니다.
    • EXIF 날짜가 없거나
    • exiftool 오류를보고하거나
    • 대상 파일 이름을 가진 파일이 이미 존재합니다.

그것은 상당히 견고합니다. 특히, 다른 답변과 마찬가지로 파일이 (자동) 사라질 수 없습니다.


0

exiv2 매우 간단한 구문을 허용하는 조작의 대안이 될 수 있습니다.

exiv2는 Exif, IPTC, XMP 메타 데이터 및 이미지 주석을 읽고 쓰는 프로그램이며 많은 공급 업체 메이커 노트 태그를 읽을 수 있습니다. 이 프로그램은 선택적으로 Exif 태그, XMP 속성 및 IPTC 데이터 세트 간을 변환합니다

따라서 현재 폴더의 모든 jpeg 이름이 변경됩니다.

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

@Kevin의 솔루션을 좋아합니다. 원래 이름도 유지하고 싶었 기 때문에 (동일한 초에 촬영 한 이미지의 문제를 피하기 위해) 여기 내 솔루션입니다.

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

0

초보자에 의한 첫 번째 게시 ... 첫 번째 bash 스크립트 ... 위의 Libor / HalosGhost 솔루션은 이름 변경에 더 자세한 내용이 포함되어 있기 때문에 마음에 들었습니다. 그러나 테스트 후 파일 이름이 중복되면 파일이 손실됩니다. 그래서 쉽게 참조하고 충돌을 방지하기 위해 파일 이름 끝에 카운터 태그를 추가했습니다. 나는 여기 누군가가 이것을 개선 할 수 있다고 확신하지만 그것이 도움이 될 것이라고 생각했습니다.

코드를 게시하여 죄송합니다. 나는 인터페이스에 어려움을 겪고 있지만 누군가가 나를 올바르게하는 방법을 지적 할 수 있다면 좋을 것입니다.

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