我每小时/每天创建一堆* .mp4和* .jpg文件,它们使用以下文件结构:
-- before:
c:\video\2017-10-15\21hour\jpg\12.13.15[M][0@0][0].jpg
c:\video\2017-10-15\21hour\mp4\12.13.01-12.14.32[M][0@0][0].mp4
c:\video\2017-10-18\16hour\jpg\21.42.31[M][0@0][0].jpg
c:\video\2017-10-18\16hour\mp4\21.42.31-21.45.38[M][0@0][0].mp4
我希望所有* .jpg和* .mp4文件都移至c:\ video \,并且也完全放弃'date_time'+扩展名的旧名称,如下所示:
-- after:
c:\video\2017-10-15_12.13.15.jpg
c:\video\2017-10-15_12.13.01-12.14.32.mp4
c:\video\2017-10-18_21.42.31.jpg
c:\video\2017-10-18_21.42.31-21.45.38.mp4
我发现了ForFiles,并能够使用/ s递归搜索所有子文件夹并将* .mp4和* .jpg移至单个位置:
forfiles /p c:\video\ /s /m *.mp4 /c "cmd /c move @PATH c:\video\"
forfiles /p c:\video\ /s /m *.jpg /c "cmd /c move @PATH c:\video\"
现在要重命名,在这一点上我几乎可以尝尝胜利,因为这可以为我提供所需的文件名输出:
forfiles /p c:\video\ /s /m *.mp4 /c "cmd /c echo @[email protected]"
forfiles /p c:\video\ /s /m *.jpg /c "cmd /c echo @[email protected]"
但是当我用ren / rename / move替换echo时,出现错误:该系统找不到指定的路径。该命令的语法不正确。
但是错误仅在我使用@FDATE和/或@FTIME时发生。这些变量都可以正常工作:@ FNAME,@ ISDIR,@ FSIZE
forfiles /p c:\video\ /m *.mp4 /c "cmd /c ren @FILE @ISDIR.@EXT"
forfiles /p c:\video\ /m *.mp4 /c "cmd /c rename @FILE @FSIZE.@EXT"
forfiles /p c:\video\ /m *.mp4 /c "cmd /c move @FILE @EXT.@EXT"
一旦重命名部分开始工作,我将把移动和重命名结合到一个命令中……但是我不知道为什么@FDATE和@FTIME无法使用,我的语法有问题吗? ,或者这仅仅是ForFiles不允许的内容?
首先,仅将echo
替换为move
或ren
不会起作用,因为它只会检测传递给它的一个参数。这可以解释语法错误。
ren
的Microsoft Docs的语法ren [<Drive>:][<Path>]<FileName1> <FileName2> rename [<Drive>:][<Path>]<FileName1> <FileName2>
move
的Microsoft Docs的语法move [{/y | /-y}] [<Source>] [<Target>]
第二,变量@FDATE
和@FTIME
与语言环境有关。它们的格式取决于您设备的区域格式,例如@FDATE
的格式可以包含/
,而@FTIME
的格式可以包含:
。这些是保留字符,如果使用不当,可能会导致错误。这可以解释路径错误。
forfiles
的解决方案如果要使用forfiles
执行此操作,则必须使用for
命令,例如this。您可以通过提取子字符串来更改日期格式,例如this answer。您可以通过用点号:
代替冒号.
来更改时间格式,说明here。
[。jpg可以再次使用/m
,. mp4可以再次使用,但也可以像this for
loop一样尝试。这意味着您必须将示例中的for
嵌套在另一个for
循环中。
根据for
,如果仅移动一个文件,也可以重命名。
move /?
如果文件数量很大,则批处理可能需要一些时间。 setlocal EnableDelayedExpansion
for %%F in (.jpg, .mp4) do (
for /f "tokens=1,2,3,4 delims=|" %%A in (
'forfiles /p "C:\video" /s /m "*%%F" /c "cmd /c echo @PATH^|@EXT^|@FDATE^|@FTIME"'
) do (
set filepath=%%~A
set extension=%%~B
set datestamp=%%~C
set timestamp=%%~D
set parseddate=!datestamp:~6,4!-!datestamp:~3,2!-!datestamp:~0,2!
move "!filepath!" "C:\video\!parseddate!_!timestamp::=.!.!extension!"
)
)
endlocal
必须先读取文件,并且forfiles
循环也必须遍历该文件列表。同样,for
是与语言环境相关的。如果您设备的区域日期格式为forfiles
,则在我的示例中子字符串的索引不正确。
。NET Framework的2020/02/10
属性与语言环境无关,因为它不依赖于设备的区域格式。如果您更喜欢使用UTC,则还有一个LastWriteTime
属性。不过,您仍然必须在批处理文件中使用LastWriteTime
循环。
PowerShell的LastWriteTimeUtc
返回由LastWriteTimeUtc
参数指定的父文件夹的所有子文件夹,使用for
参数可以递归地执行此操作。如果您希望结果仅包含.jpg和.mp4文件,则应使用Get-ChildItem
。通常,在使用Get-ChildItem
时,您需要在路径上附加-Path
,但是由于使用了-Recurse
,因此没有必要。
使用-Include *.jpg, *.mp4
和-Include
参数,您可以列出\*
,-Recurse
和Get-ItemProperty
属性。为了使Get-ItemProperty
循环更具可读性,必须像-Name
这样调用它们并将其串联。必须使用Fullname
将LastWriteTime
转换为字符串并更改其格式。
Extension
注意:您可以省略for
,但是第一个参数必须是路径。