[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文件操作] JPG文件匹配CR2文件的批处理,如何增加一个拍摄时间相同才匹配呢?

  1. @echo off
  2. rem 测试前先备份原文件
  3. for /f "delims=" %%a in ('dir /a-d/b/s *.jpg') do (
  4.     if exist "..\CR2-1\%%~na.cr2" (
  5.         copy "..\CR2-1\%%~na.cr2" "%%~dpa" /y
  6.     ) else (
  7.         if exist "..\CR2-2\%%~na.cr2" copy "..\CR2-2\%%~na.cr2" "%%~dpa" /y
  8.     )
  9. )
  10. pause
复制代码
因为CR2-1和CR2-2存在文件名相同的情况,匹配起来会错乱,是否可以增加一个拍摄时间一致的条件呢?

本帖最后由 77七 于 2024-9-13 15:57 编辑
  1. @echo off
  2. cd /d "%~dp0"
  3. for /f "delims=" %%i in ('dir /b /s /a-d *.jpg') do (
  4. for %%j in ("..\cr2-1\%%~ni.cr2" "..\cr2-2\%%~ni.cr2") do (
  5. if "%%~ti" equ "%%~tj" (
  6. copy "%%~j" "%%~dpi"
  7. )
  8. )
  9. )
  10. pause
复制代码
bat小白,请多指教!谢谢!

TOP

本帖最后由 aloha20200628 于 2024-9-19 21:17 编辑

回复 1# 228630386
  1. @echo off & for /f "delims=" %%i in ('dir /b /s /a-d *.jpg') do (
  2. for %%a in ("..\CR2-1\%%~ni.cr2") do if "%%~ti"=="%%~ta" copy "..\CR2-1\%%~ni.cr2" "%%~dpi" /y
  3. for %%a in ("..\CR2-2\%%~ni.cr2") do if "%%~ti"=="%%~ta" copy "..\CR2-2\%%~ni.cr2" "%%~dpi" /y
  4. )
  5. pause&exit/b
复制代码

以上代码匹配的是*.jpg文件与对应的*.cr2文件的 ‘最后修改时间’ 是否一致

TOP

回复 3# aloha20200628


    运行后没有提示拷图信息。

TOP

回复 2# 77七


    也是没有提示拷贝成功

TOP

回复 5# 228630386


   http://bbs.bathome.net/thread-69-1-1.html
试试此代码,将照片修改时间改为拍摄时间,再用2楼代码。
bat小白,请多指教!谢谢!

TOP

本帖最后由 ppll2030 于 2024-9-19 22:27 编辑

没有cr2文件,就用jpg和jpeg来测试,测试通过。只要文件有exif信息并有拍摄时间,就可以获取并比对。
脚本保存为bat,跟jpg文件放一块,运行即可把同名且拍摄时间一致的cr2文件复制过来。
需匹配的文件夹cr2-1、cr2-2均在jpg文件夹外。如路径不对,请自行修改第6行。
  1. @echo off &setlocal enabledelayedexpansion
  2. >temp.vbs echo Set objFSO = CreateObject("Scripting.FileSystemObject"):Set objFile = objFSO.GetFile(WScript.Arguments(0)):Set shell = CreateObject("Shell.Application"):Set folderitem = shell.Namespace(objFile.ParentFolder.Path).ParseName(objFile.Name):WScript.Echo folderitem.ExtendedProperty("System.Photo.DateTaken")
  3. for /f "delims=" %%i in ('dir /b /a-d *.jpg') do (
  4. for /f "delims=" %%x in ('cscript //nologo temp.vbs "%%i"') do set a=%%x
  5. for /f "delims=" %%f in ('dir /b /s /a-d "..\CR2-1\%%~ni.cr2" "..\CR2-2\%%~ni.cr2"') do (
  6. for /f "delims=" %%x in ('cscript //nologo temp.vbs "%%f"') do set b=%%x
  7. if "!a!" == "!b!" (copy %%f "%%~dpi" /y)
  8. )
  9. )
  10. del temp.vbs&pause
复制代码
想到一个个获取时间对于大量图片可能速度有点慢,再弄一个提提速度
先获取所有图片的时间到临时文件,再挨个匹配,理论上应该可以省很多时间。欢迎楼主测试。
  1. @echo off &setlocal enabledelayedexpansion
  2. >temp.vbs echo Set objFSO = CreateObject("Scripting.FileSystemObject"):Path = WScript.Arguments(0):Set Text = objFSO.CreateTextFile(WScript.Arguments(1)):Set Shell = CreateObject("Shell.Application"):Set objPath = Shell.NameSpace(Path):For Each File In objFSO.GetFolder(Path).Files:If LCase(Right(File.Name,4))=".jpg" Or LCase(Right(File.Name,4))=".cr2" Then:Set objFile = objPath.ParseName(File.Name):strDateTaken = objFile.ExtendedProperty("System.Photo.DateTaken"):Text.WriteLine File.Name ^& ":" ^& strDateTaken:End If:Next:Text.Close
  3. cd..
  4. set "pd=%cd%"
  5. cd %~dp0
  6. cscript //nologo temp.vbs "%cd%" "$.txt"
  7. cscript //nologo temp.vbs "%pd%\CR2-1" "$1.txt"
  8. cscript //nologo temp.vbs "%pd%\CR2-2" "$2.txt"
  9. for /f "tokens=1*delims=:" %%a in ($.txt) do (
  10. for /f "tokens=1*delims=:" %%x in  ('type $1.txt^|findstr /ic:"%%~na"') do (
  11. if "%%b" == "%%y"  copy "%pd%\CR2-1\%%x" %~dp0 /y)
  12. for /f "tokens=1*delims=:" %%x in  ('type $2.txt^|findstr /ic:"%%~na"') do (
  13. if "%%b" == "%%y"  copy "%pd%\CR2-2\%%x" %~dp0 /y)
  14. )
  15. del $*.txt temp.vbs&pause
复制代码
1

评分人数

TOP

回复 7# ppll2030


    我去,居然有这个属性 folderitem.ExtendedProperty
测试可行

在哪找到这个属性的?
https://learn.microsoft.com/en-us/windows/win32/shell/folderitem#properties
微软网站的没更新么

QQ 20147578

TOP


QQ 20147578

TOP

回复 8# czjt1234


    嗯。之前网上搜索到的。找了两三个,就这个好用。具体不记得在哪了

TOP

本帖最后由 aloha20200628 于 2024-9-20 12:22 编辑

回复 4# 228630386

看来假设 *.jpg 和 *.cr2 对应文件存在 ‘修改时间’ 的一致性是没戏了...
用 vbs/jscript/powershell/python 等脚本获取图片文件内置的 ‘拍摄时间’ 有多种方法,vbs/jscript 可以调用 Shell.Application 或 WIA.imageFile
7楼用 ExtendedProperty("System.Photo.DateTaken") 获取的属性值用 win8.1 实测要比资源管理器显示的图片文件拍摄时间差了8小时
改用 GetDetailsOf() 的 ‘date Taken’ 属性 或 WIA.imageFile 方法中的 ‘ExifDTOrig’ 属性值均无误差
以下代码存为 test.bat 运行,其中调用 WIA.imageFile 方法获取图片文件拍摄时间...
  1. @set @v=1 /* &echo off
  2. (for /f "delims=" %%i in ('dir /b/s/a-d *.jpg') do for %%p in (
  3.      "CR2-1","CR2-2") do for /f "delims=" %%a in (
  4.      'dir /b/s "..\%%~p\%%~ni.cr2" ') do for /f "tokens=1-2 delims=;" %%x in (
  5.      'cscript /e:jscript "%~f0" "%%i" "%%a" ') do if "%%x"=="%%y" copy "..\%%~p\%%~ni.cr2" "%%~dpi" /y
  6. ) 2>nul
  7. pause&exit/b */
  8. v=WSH.arguments, img=WSH.createObject('WIA.imageFile'), s='';
  9. for (k=0; k<2; k++) {
  10.      img.loadFile(v(k));
  11.      if (img.properties.count<1 || !img.properties.exists('ExifDTOrig')) WSH.quit();
  12.      s+=img.properties.item('ExifDTOrig').value+';'
  13. }
  14. WSH.echo(s), WSH.quit();
复制代码

TOP

回复 11# aloha20200628

感谢大佬的指点。
不过貌似WIA不支持.jpg以外的格式图片,就连jpeg都无法读取。
GetDetailsOf的属性索引号貌似不同系统下,可能会不一致,从而导致取数错误。
所以两个都放弃了。选择了System.Photo.DateTaken
当时没细看 ,日期对上,时间差8小时,应该是系统的时区差造成的。
不过在这里应该不影响处理结果。毕竟所有文件都有时差,匹配还是可以成功滴。

TOP

回复 12# ppll2030


    有反馈才有动力,赞一个

QQ 20147578

TOP

回复 11# aloha20200628


    *.jpg 和 *.cr2 对应文件存在 ‘修改时间’ 的一致性是没戏了...,修改时间一致这个问题确实存在的,匹配拍摄时间才不会出错。

TOP

本帖最后由 aloha20200628 于 2024-9-21 11:19 编辑

回复 14# 228630386

模拟一楼示例的目录文件结构,且用一楼的代码作了一个简单测试,有以下结论》
一。只要 dir /b/s/a-d *.jpg 列表中没有同名文件,即使 "..\CR2-1\" 和 "..\CR2-2\" 两个目录中有重名文件,也不会出现 *.cr2 文件复制到 "%%~dpi" 重名的结果,因为一楼代码采用了 ‘逻辑或’ 的分支处理方法。
二。仅当 dir /b/s/a-d *.jpg 列表中有同名文件时,无论 "..\CR2-1\" 和 "..\CR2-2\" 两个目录中是否有重名文件,都会出现*.cr2 文件复制到 "%%~dpi" 重名的结果。
三。增加 ‘时间比对’ 的筛选条件,只是减少了复制结果的数量,并未消除复制同名的根本原因,即如果 dir /b/s/a-d *.jpg 列表与 CR2-* 目录中存在 ‘时间比对一致’ 的同名文件,依然会出现复制同名的结果。目前一楼代码事实上对此重名结果的处理就是通过 copy ... /y 实现简单覆盖...

TOP

返回列表