我的任务是创建照片的每月备份,这些照片需要从他们的位置移动到其他地方,按日期排序到文件夹中,然后按月批量刻录到磁盘。
理论上这应该是简单的,即使它是一个新的过程,我们有大约一年的照片,一旦我们可以从现在开始每个月运行一次。
首先想到的是:
从位置“A”复制到位置“B”,根据创建日期“MONTH \ YEAR”排序到子文件夹,将每个文件夹刻录到磁盘。
这很简单,如果是这样的话,现在就可以了,我的问题是这样的:
所有照片都来自我们提供服务的其他公司,有大约15家公司,每家公司都有自己的文件夹。每个文件夹里面还有5个文件夹,其中一个有图像,其他有配置文件数据库备份等等。
作为一个例子,结构是:
─Data
├─Company1
│├───图像
│├───其他1 │└───其他2
├─Company2
│├───图像
│├───其他1 │└───其他2
└─Company3
├───IMAGES
├───Other1
└───其他2
因此,在每个“IMAGE”文件夹中,不按日期排序的照片。我只需要将这些文件夹复制到如下所示的结构:
──Backups
├─01-15
│├───公司1 │├───公司2 │└───公司3 ├─02-15
│├───公司1 │├───公司2 │└───公司3 └─03-15
├───Company1
├───Company2
└───公司3
这样我可以简单地将每个月的文件夹刻录到自己的磁盘上,并且所有图像都按公司排序。
所以创建一个名为“MONTH-YEAR”的文件夹然后在其中,为每个公司“Company1”“Company2”等创建文件夹,然后在每个文件夹中都有该公司和那个月的照片。
我试图批量写这个几乎成功。虽然我不再拥有代码(在它没有工作太多次之后烦恼地将其删除:/),它使用了很多嵌套的IF语句和变量被设置来维护父文件夹的父文件夹的名称等然后循环以在下一个文件夹上执行整个过程...
这么长的故事,我需要一些方法来根据日期和文件夹上面两个级别的名称将图像移动到文件夹中。此外,如果它可以创建被复制到其中的文件夹,那将是很好的 即使有人可以提供一些从批处理(或VBS)开始的指针,或者一些我可以解决的伪代码,我也会非常感激。
非常感谢,
这个迷茫的新手!
答案 0 :(得分:2)
这些解决方案假设目录列表将文件时间戳显示为“MM / DD / YYYY HH:MM:SS PM”。如果您的语言环境的时间戳格式不同,则必须修改代码。
我强烈建议您使用YYYY-MM格式命名日期文件夹,以便按时间顺序排序。此外,你不应该使用两位数的年份 - 我经历了Y2K的噩梦 - 这是不值得的。
如果日期来自每个文件的最后修改日期,则相当容易--~t修饰符提供文件的最后修改日期:
%= Iterate company folders =%
for /d %%D in ("Data\*") do (
%= Iterate images under company folder =%
for %%F in ("%%D\IMAGES\*") do (
%= Parse last modified month and year for the file =%
for /f "delims=/ tokens=1,3" %%A in ("%%~tF") do (
%= Create the destination folder - ignore error if already exists =%
md "Backup\%%B-%%A\%%~nxD" 2>nul
%= Move the file =%
move "%%F" "Backup\%%B-%%A\%%~nxD" >nul
)
)
)
如果您想要创建日期,那么它会更复杂一些。我使用DIR / TC选项来获取创建日期,并且必须从DIR列表中解析日期和文件名。
%= Iterate company folders =%
for /d %%A in ("Data\*") do (
%= Iterate images under company folder, parsing out created date and file name =%
for /f "tokens=1,4*" %%B in (
'dir /a-d /tc "%%A\images"^|findstr /rc:"^[^ ]"'
) do (
%= Parse the month and year from created date =%
for /f "delims=/ tokens=1,3" %%E in ("%%B") do (
%= Create the destination folder - ignore error if already exists =%
md "Backup\%%C-%%B\%%~nxA" 2>nul
%= Move the file =%
move "%%A\images\%%D" "Backup\%%C-%%B\%%~nxA" >nul
)
)
)
可以使用WMIC以区域设置无关的方式获取创建日期或上次修改日期。但是编码变得非常复杂,需要大量的奥术技巧才能以有效的方式获得所需的结果。以下代码假定您需要创建日期。要使用上次修改日期,只需将creationDate
更改为lastModified
。
@echo off
:: FOR loop variables must be expanded with delayed expansion off
:: otherwise values containing ! will be corrupted
setlocal disableDelayedExpansion
%= Iterate company folders =%
for /d %%D in ("Data\*") do (
%= Parse drive, company, and image path info =%
%= Enable delayed expansion to access variables set within loop =%
%= Escape \ in path for use with WMIC =%
set "drive=%%~dD"
set "company=%%~nxD"
set "imagePath=%%~pnxD"
setlocal enableDelayedExpansion
set "imagePath=!imagePath:\=\\!\\IMAGES\\"
%= Iterate images and creation dates for files under company folder using WMIC =%
%= Two FOR /F loops are used to eliminate trailing <CR> character from each line =%
%= The trailing <CR> is an odd artifact of conversion of WMIC unicode output =%
for /f "skip=1 delims=" %%A in (
'wmic datafile where "drive='!drive!' and path='!imagePath!'" get creationDate^, name 2^>nul'
) do for /f "tokens=1*" %%B in ("%%A") do (
%= Disable delayed expansion again to protect ! =%
setlocal disableDelayedExpansion
%= Save the date and file info. The file will have trailing spaces, but that =%
%= is OK because Windows ignores trailing spaces and dots in file names =%
set "date=%%B"
set "image=%%C"
%= Re-enable delayed expansion and parse out year and month to compute destination =%
setlocal enableDelayedExpansion
set "destination=Backup\!date:~0,4!-!date:~4,2!\!company!"
%= Create the destination folder - ignore error if already exists =%
md "!destination!" 2>nul
%= Move the file =%
move "!image!" "!destination!" >nul
%= Pop the setlocal stack to get back to state before inner loop started =%
endlocal
endlocal
)
%= Pop the setlocal stack to get back to state before outer loop started =%
endlocal
)
如果您使用我的JREN.BAT实用程序,它可以变得更容易,该实用程序可以以区域设置无关的方式解析和格式化文件时间戳。 JREN.BAT主要用于使用正则表达式重命名文件。但它有一个列表模式,允许您将文件名转换为几乎任何内容,而无需重命名,然后可以使用FOR / F进行解析。
以下代码使用创建日期。如果您想使用上次修改日期,请将created
更改为modified
。
@echo off
:: JREN does most of the work.
:: /LIST option lists the final "rename" value, without renaming anything
:: /P specifies root path
:: /S iterates all sub-folders
:: /PM determines which sub-folders to look at, /P: matches the root path
:: /J treats replacement value as JScript code
:: The "^.*" search matches the entire file name
:: The "ts({dt:'created',fmt:'{yyyy}-{mm} '})+path()" replacement
:: gets and formats the creation date using WMI
:: followed by the full path to the image file
:: The JREN output looks like: YYYY-MM fullPathToImage
for /f "tokens=1*" %%A in (
'jren "^.*" "ts({dt:'created',fmt:'{yyyy}-{mm} '})+path()" /list /j /s /p "Data" /pm "/P:\*\IMAGES"'
) do (
%= Get the company name from the fullImagePath =%
for %%C in ("%%B\..\..") do (
%= Create the destination folder - ignore error if already exists =%
md "Backup\%%A\%%~nxC" 2>nul
%= Move the file =%
move "%%B" "Backup\%%A\%%~nxC" >nul
)
)
答案 1 :(得分:1)
因此,不是通过图像的祖父母文件夹来抓取公司名称,而是由#34;数据&#34;的孩子抓住它。这可以通过子例程中的一些string manipulation来完成。
在for
循环中,%%~tX
具有每个文件的最后修改日期。使用几个嵌套的for
循环来按空格分割该字符串,然后使用斜杠可以非常轻松地将日期按到MM-YYYY
。 修改:我looked up the date format用于新西兰语区域设置,我认为我已正确配置脚本以便为您划分月份和年份。试一试,看看它是如何工作的。 (如果我试图使这个区域设置无关,我可能会查询wmic datafile
每个文件,但这有点像工作。请告诉我你是否需要它。)
@echo off
setlocal enabledelayedexpansion
set "source=c:\Data"
set "destination=d:\Backup"
:: for every image file recursively in %source%
for /r "%source%" %%I in (*.jpg *.png *.gif *.bmp *.xcf *.psd) do (
rem :: get company name from directory 1 level within "Data"
call :getCompany company "%%~dpI"
rem :: get month-year from file last modified date
rem :: note: assumes ~t is in format of dd/mm/yy hh:mm
for /f %%a in ('echo %%~tI') do (
for /f "tokens=2,3 delims=/" %%x in ('echo %%a') do (
set "fdate=%%x-%%y"
)
)
set "folder=%destination%\!fdate!\!company!\"
if not exist "!folder!" md "!folder!"
<NUL set /P "=Copying %%~nxI to !fdate!\!company!\... "
>NUL copy "%%~fI" "!folder!"
echo Done.
)
goto :EOF
:getCompany <var_to_set> <path>
setlocal
set "company=%~2"
set "company=%company:*Data\=%"
set company=%company:\=&rem.%
endlocal & set "%~1=%company%"