이 오래된 게시물에는 댓글을 달 수 없습니다.
EXIF 데이터를 기반으로 사진 이름을 바꾸는 방법은 무엇입니까?
하지만 그 댓글이 나에게 딱 필요한 것 같아서 좋은 형태로 새 게시물을 시작했습니다.
jhead에서 grep 및 SED를 거쳐 코드가 수행하는 작업을 이해합니다.
for i in *.JPG; do
j=`jhead "$i" | grep date | sed 's/^File date[^:]\+: \(.\+\)$/\1/'`.jpg
echo mv -i "$i" "$j"
done
나는 매우 유사한 결과를 원하지만 날짜를 약간 수정하고 싶습니다. 이름 바꾸기/출력: yyyymmdd-hhmmss 하지만 SED 정규식을 파악(번역)할 수 없습니다. 나는 노력했다
sed 's/^File date[^:]\+: \(\d{4}\):\(\d\d\):\(\d\d\) \(\d\d\):\(\d\d\):\(\d\d\)$/\1\2\3-\4\5\6/'
하지만 내가 얻는 것은
File date : yyyy:mm:yy hh:mm:ss
저는 SED와 이를 작동시키는 정규식을 배우는 데 정말 관심이 있고 SED가 스트림 편집에 매우 강력하다는 것을 깨달았습니다. 저는 이 부분을 특별히 이해하지 못합니다. [^:] $가 EOL을 의미하는 것처럼 캐럿은 때때로 BOL을 의미한다고 생각했습니다... 하지만 이 글을 게시하려고 시도하고 다른 SED 게시물을 보면서 "^"라는 것을 (다시?) 알게 되었습니다. 아마도 "not"을 의미하므로 [^:]는 "match NOT :"을 의미합니다..? 하지만:
어쨌든 나는 길을 잃었다.
답변1
AFAICT, 날짜 문자열의 공백을 문자로 변경하려는 것 같나요 -
?
이것은 실제로 매우 간단합니다. 하지만 먼저 이 쉘 스크립트에는 몇 가지 문제가 있습니다. 첫째, $(
명령 대체 대신 백틱을 사용합니다 )
. 둘째, 불필요하게 grep을 사용합니다(sed는 여기서 grep이 수행하는 작업을 수행할 수 있습니다). 셋째, 수행하려는 정규식 검색 및 바꾸기는 한 단계보다 두 단계로 수행하는 것이 더 쉽습니다(먼저 줄의 "파일 날짜" 부분을 제거한 다음 나머지 날짜 문자열을 수정).
향상된 스크립트 버전은 다음과 같습니다.
for i in *.JPG; do
j=$(jhead "$i" | sed -n -E '/^File date/ { s/^File date +: +//; s/ /-/p}').jpg
echo mv -i "$i" "$j"
done
영어: jhead
명령의 출력은 sed로 파이프됩니다. sed 옵션은 -n
(print) 문을 통해 지시하지 않는 한 sed에게 어떤 줄도 인쇄하지 않도록 지시합니다. p
이 -E
옵션은 BRE(기본 정규 표현식) 대신 ERE(확장 정규 표현식)를 사용하도록 지시합니다. 이는 주로 수정자를 사용하여 +
하나 이상의 공백과 일치시킬 수 있도록 하기 위한 것입니다.
sed 스크립트 자체는 먼저 행이 "파일 날짜"로 시작하는지 확인합니다. 그렇다면 sed 명령 블록(즉, {
sum으로 묶인 두 개 이상의 명령 }
)을 실행합니다.
블록의 첫 번째 명령은 줄에서 "파일 날짜"를 제거한 다음 하나 이상의 공백, 콜론, 하나 이상의 공백을 제거합니다. 그러면 날짜만 포함된 행이 생성됩니다.
두 번째 명령은 첫 번째(유일한) 공백 문자를 대시로 변경합니다 -
. p
명령 끝에는 s///
sed에게 수정된 줄을 인쇄하라고 지시하는 가 있습니다.
실행 예시:
$ ls -l *.JPG
-rw-r--r-- 1 cas cas 1110176 Oct 20 14:04 abc.JPG
-rw-r--r-- 1 cas cas 1132711 Oct 20 14:04 def.JPG
-rw-r--r-- 1 cas cas 1061121 Oct 20 14:04 ghi.JPG
$ for i in *.JPG; do
j="$(jhead "$i" |sed -n -E '/^File date/ { s/^File date +: +//; s/ /-/p }').jpg"
echo mv -i "$i" "$j"
done
mv -i abc.JPG 2021:10:20-14:04:08.jpg
mv -i def.JPG 2021:10:20-14:04:09.jpg
mv -i ghi.JPG 2021:10:20-14:04:10.jpg
그런데 이 스크립트는 특별히 안전하지 않습니다. 예를 들어, 두 개의 서로 다른 jpeg 파일이 정확히 동일한 타임스탬프를 가질 수 있다는 사실을 고려하지 않습니다.
다음과 같은 것은 완벽과는 거리가 멀지만 더 안전하거나 더 좋을 것입니다.
for i in *.JPG; do
j="$(jhead "$i" | sed -n -E '/^File date/ { s/^File date +: +//; s/ /-/p }')"
c=1
while [ -e "$j-$c.jpg" ] ; do
let c+=1
done
j="$j-$c"
mv -iv "$i" "$j.jpg"
done
(참고: 이 버전은 실제로 파일 이름을 변경합니다. 이는 단지 수행할 작업이 아닙니다 echo
. 이 작업을 수행하지 않으면 카운터 변수를 언제 증가시켜야 할지 알 수 없기 때문에 테스트에 필요합니다. $c
)
출력 예:
renamed 'abc.JPG' -> '2021:10:20-14:04:08-1.jpg'
renamed 'def.JPG' -> '2021:10:20-14:04:08-2.jpg'
renamed 'ghi.JPG' -> '2021:10:20-14:04:08-3.jpg'
그런데, 동일한 타임스탬프를 가진 jpeg 파일이 9개 이상 있을 수 있는 경우 이를 사용하여 printf
카운터가 2자리 또는 3자리이고 0으로 채워졌는지 확인할 수 있습니다. 예를 들어
for i in *.JPG; do
j="$(jhead "$i" | sed -n -E '/^File date/ { s/^File date +: +//; s/ /-/p }')"
c=1
while [ -e "$(printf "%s-%03i.jpg" "$j" "$c")" ] ; do
let c+=1
done
j="$(printf "%s-%03i.jpg" "$j" "$c")"
mv -iv "$i" "$j"
done
renamed 'abc.JPG' -> '2021:10:20-14:04:08-001.jpg'
renamed 'def.JPG' -> '2021:10:20-14:04:08-002.jpg'
renamed 'ghi.JPG' -> '2021:10:20-14:04:08-003.jpg'
RE: 캐럿에 관한 질문입니다 ^
.
대괄호 표현식 외부에서는 줄 시작 앵커입니다. 예를 들어 ^File date
"파일 날짜"와 일치합니다.오직줄의 시작 부분에.
대괄호 표현식 내에서는 표현식의 의미를 부정/반전합니다. 예를 들어 [A-Z]
A부터 Z까지의 모든 문자와 일치하는 것은 [^A-Z]
아래의 모든 문자와 일치합니다.아니요A와 Z 사이.
답변2
바퀴를 재발명하는 이유는 무엇입니까?
jhead
원하는 것을 정확하게 수행하도록 선택할 수 있습니다.
-n[형식 문자열] 이 옵션을 사용하면 Exif 헤더 "DateTimeOriginal" 필드의 날짜 정보를 사용하여 파일 이름이 바뀌거나 이동됩니다. ].
동일한 타임스탬프가 있는 여러 사진을 고려해 보세요.
대상 이름이 이미 존재하는 경우 이름에 "a", "b", "c" 등이 추가됩니다. 단, 이름이 문자로 끝나는 경우에는 "0", "1"이 추가됩니다. ", "2" 잠깐만요
예:
jhead -n%Y%m%d-%H%M%S *.JPG
답변3
감사해요모두매우. 멍청한 질문을 할까봐 걱정됐지만 배우고 싶어서 그냥 던져버렸어요. 그렇기 때문에 이것이 바퀴를 재발명하는 것일 수도 있지만 나는 뭔가를 배웠습니다. Jhead 자신이 모든 것을 해냈을 수도 있는 것처럼 @pLumo에게 감사드립니다. 저를 화나게 하는 것은 SED의 음모와 (잊혀진) 정규식입니다. 좀 더 생각해 본 결과 [^:]+가 (@cas에게 감사드립니다)라는 것을 알 수 있었습니다. search for one or more characters that are NOT ":"
불행히도 저는 너무 느립니다.그롱크이전의 것. 그리고 [[:digit:]]를 사용하는 SED의 구문을 모르겠습니다. 그래서 내가 만들려고하는 라인은 다음과 같습니다
j=`jhead "$i" | grep date | sed 's/^File date[^:]\+: \([[:digit:]]\{4\}\):\([[:digit:]]\{2\}\):\([[:digit:]]\{2\}\) \([[:digit:]]\{2\}\):\([[:digit:]]\{2\}\):\([[:digit:]]\{2\}\)$/\1\2\3-\4\5\6/'`.jpg
@cas 이 경우 예 공백으로 변경하고 ":"도 제거합니다. SED 일치 번호를 만드는 방법을 배우면 구분 기호를 바꾸는 것뿐만 아니라 원하는 형식/패턴을 구성할 수 있습니다.
내 가장 큰 정신적 장애물은 너무 많은 피연산자가 이스케이프되는 데서 오는 것 같습니다(올바른 용어이기를 바랍니다). 백슬래시는 ..모든 것! 난 그냥 할 수 없어그롱크그게 다야.
귀하의 모든 제안으로 인해 더 많은 코딩 도구/기술이 제공되었으며 더 많은 초보자 질문을 하기 전에 찾을 수 있도록 메모하려고 노력하고 있습니다! 매우 감사합니다
포스팅 직후 천둥번개가 쳤기 때문에 방법을 찾아도 곧 답글을 올릴 수 없었습니다. 데스크톱과의 연결을 끊어야 하고 휴대전화를 약간의 검색에만 사용할 수 있었습니다. 모바일에서 기사를 작성하는 데는 별로 쓸모가 없습니다.
답변4
사용 해주세요EXIV2CLI 도구는 다음과 같습니다.
exiv2 -r "IMG_%Y%m%d_%H%M%S" -F *
현재 디렉터리에 이미지 파일이 포함되어 있는 경우.
이미지 EXIF 메타데이터를 쿼리하여 많은 작업을 수행할 수 있습니다. 특히 를 사용하면 -r
그에 따라 파일 이름을 바꿀 수 있습니다.
전체 세부 사항을 보려면 링크된 페이지를 방문하고 전체 옵션 세트를 보려면 맨 페이지를 방문하십시오.