将视频文件从图片目录移至视频目录
我的照片导入工具(Picasa)在从手机和相机导入照片和视频方面做得非常出色。我喜欢的是它根据每张照片/视频的拍摄日期在图片目录下创建一个子文件夹。所以你最终得到这样的结构:将视频文件从图片目录移至视频目录
C:\Pictures\2017-02-01\DSC_0001.jpg
C:\Pictures\2017-02-01\DSC_0002.jpg
C:\Pictures\2017-02-01\DSC_0003.mp4 <--- problem
唯一的问题是它把视频放在这个相同的结构下图片。
因此,我想要一个批处理脚本来查找并将所有视频文件(.mp4,.avi,.mov)从C:\ Pictures目录移动到C:\ Videos目录,但也随着日期的子文件夹.... 即
Move C:\Pictures\2017-02-01\DSC_0003.mp4 to C:\Videos\2017-02-01\DSC_0003.mp4
注意日期的子文件夹可能会或可能不会在存在C:\影片。
此外,由于这些视频文件很大,并且有很多视频文件,所以我更喜欢一个实际执行移动而不是复制然后删除的进程,这是为了提高速度和磁盘空间利用率,几乎没有空间(重新组织这些文件后,我将归档到NAS)。
还喜欢使用RoboCopy,xcopy或xxcopy,因为我拥有它们并在我的机器上今天使用它们。如果使用PowerShell脚本更容易,我可以知道如果它很容易做到。
最终解决 我用渔业部的回答,但增强它只是有点添加一个函数来计算目录字符串长度
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Define folder with the pictures which is never deleted.
set "PicturesFolder=D:\Users\Chad\PicturesTest"
rem get string length of source directory to later use in a substring type function
call :strlen PicturesFolderDirectoryLength PicturesFolder
echo PicturesFolderDirectoryLength = %PicturesFolderDirectoryLength%
rem Change the current directory to directory with the pictures.
cd /D "%PicturesFolder%"
rem Search recursive in this directory for video files with
rem file extension AVI, MOV, MP4 or MPG and move those files.
for /F "delims=" %%I in ('dir /A-D /B /S *.avi *.mov *.mp4 *.mpg 2^>nul') do call :MoveVideo "%%I"
rem Discard all environment variables defined in this batch code
rem and restore initial current directory before exiting batch file.
endlocal
goto :EOF
rem MoveVideo is a subroutine called with name of current
rem video file name with full path by the FOR loop above.
rem It first defines target path for video file depending on source path
rem by removing the backslash at end and concatenating C:\Videos with the
rem source path omitting the first 11 characters which is C:\Pictures.
rem Then the target directory structure is created with redirecting the
rem error message output by command MD to handle STDERR in case of the
rem target directory already exists to device NUL to suppress it.
rem Next the video file is moved from source to target folder with silently
rem overwriting an already existing file with same name in target folder
rem because of using option /Y. Remove this option if a video file should
rem be kept in pictures folder and an error message should be displayed in
rem case of a video file with same name already existing in target folder.
rem Last the source folder is removed if it is completely empty which means
rem it does not contain any file or subfolder. All parent folders up to the
rem pictures folder are also removed if each parent folder is also empty
rem after deletion of an empty folder.
rem The subroutine is exited with goto :EOF and execution of batch file
rem continues in main FOR loop above with next found video file.
:MoveVideo
set "SourcePath=%~dp1"
set "SourcePath=%SourcePath:~0,-1%"
ECHO SourcePath=%SourcePath%
CALL SET "SourceSubFolder=%%SourcePath:~%PicturesFolderDirectoryLength%%%"
ECHO SourceSubFolder=%SourceSubFolder%
set "TargetPath=D:\Users\Chad\VideosTest%SourceSubFolder%"
echo TargetPath=%TargetPath%
md "%TargetPath%" 2>nul
move /Y "%~1" "%TargetPath%\%~nx1" >nul
:DeleteSourceFolder
rd "%SourcePath%" 2>nul
if errorlevel 1 goto :EOF
for /F "delims=" %%D in ("%SourcePath%") do set "SourcePath=%%~dpD"
set "SourcePath=%SourcePath:~0,-1%"
if /I not "%SourcePath%" == "%PicturesFolder%" goto DeleteSourceFolder
goto :EOF
:strlen <resultVar> <stringVar>
(
setlocal EnableDelayedExpansion
set "s=!%~2!#"
set "len=0"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!s:~%%P,1!" NEQ "" (
set /a "len+=%%P"
set "s=!s:~%%P!"
)
)
)
(
endlocal
set "%~1=%len%"
exit /b
)
这是一个注释的批处理代码文件移动任务与保持目录结构。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Define folder with the pictures which is never deleted.
rem Note: ~11 in third line of subroutine MoveVideo must be
rem replaced by ~length of the folder path defined here.
set "PicturesFolder=C:\Pictures"
rem Change the current directory to directory with the pictures.
cd /D "%PicturesFolder%"
rem Search recursive in this directory for video files with
rem file extension AVI, MOV, MP4 or MPG and move those files.
for /F "delims=" %%I in ('dir /A-D /B /S *.avi *.mov *.mp4 *.mpg 2^>nul') do call :MoveVideo "%%I"
rem Discard all environment variables defined in this batch code
rem and restore initial current directory before exiting batch file.
endlocal
goto :EOF
rem MoveVideo is a subroutine called with name of current
rem video file name with full path by the FOR loop above.
rem It first defines target path for video file depending on source path
rem by removing the backslash at end and concatenating C:\Videos with the
rem source path omitting the first 11 characters which is C:\Pictures.
rem Then the target directory structure is created with redirecting the
rem error message output by command MD to handle STDERR in case of the
rem target directory already exists to device NUL to suppress it.
rem Next the video file is moved from source to target folder with silently
rem overwriting an already existing file with same name in target folder
rem because of using option /Y. Remove this option if a video file should
rem be kept in pictures folder and an error message should be displayed in
rem case of a video file with same name already existing in target folder.
rem Last the source folder is removed if it is completely empty which means
rem it does not contain any file or subfolder. All parent folders up to the
rem pictures folder are also removed if each parent folder is also empty
rem after deletion of an empty folder.
rem The subroutine is exited with goto :EOF and execution of batch file
rem continues in main FOR loop above with next found video file.
:MoveVideo
set "SourcePath=%~dp1"
set "SourcePath=%SourcePath:~0,-1%"
set "TargetPath=C:\Videos%SourcePath:~11%"
md "%TargetPath%" 2>nul
move /Y "%~1" "%TargetPath%\%~nx1" >nul
:DeleteSourceFolder
rd "%SourcePath%" 2>nul
if errorlevel 1 goto :EOF
for /F "delims=" %%D in ("%SourcePath%") do set "SourcePath=%%~dpD"
set "SourcePath=%SourcePath:~0,-1%"
if /I not "%SourcePath%" == "%PicturesFolder%" goto DeleteSourceFolder
goto :EOF
此批处理文件同时删除C:\Pictures
这成为移动视频文件后,空的所有文件夹。但它不会删除启动批处理文件时已空的文件夹。
为了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
cd /?
echo /?
endlocal /?
for /?
goto /?
if /?
md /?
move /?
rd /?
rem /?
set /?
setlocal /?
阅读也是微软的文章关于Using Command Redirection Operators为>nul
和2>nul
的解释。在主FOR循环重定向操作符>
转义与脱字符^
被解释为文字字符上解析FOR命令行和后来由FOR上DIR
执行命令行的重定向操作符。
工作像一个魅力和很好的功能,以删除空的源目录!加上优秀的代码文档!我稍微增强了您的解决方案,以便具有计算源文件夹目录长度的功能,以便在未来需要将其用作其他任务的基准时不使用硬编码。查看原始问题中更新的最终答案。 –
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
XCOPY /T "%sourcedir%" "%destdir%"
FOR %%x IN (mp4 mov) DO (
FOR /f "tokens=1*delims=>" %%a IN (
'XCOPY /Y /s /d /F /L "%sourcedir%\*.%%x" "%destdir%"'
) DO IF "%%b" neq "" (
SET "topart=%%b"
SET "frompart=%%a"
ECHO(MOVE /y "!frompart:~0,-2!" "!topart:~1!"
)
)
GOTO :EOF
你需要改变的sourcedir
的设置和destdir
以适应您的情况。
所需的MOVE命令仅为ECHO
用于测试目的。 确认命令正确后,将ECHO(MOVE
更改为MOVE
以实际移动文件。追加>nul
打压报告消息(例如,1 file moved
)
第一xcopy
创建所需的子树,第二个使用/L
选项列表,而不是复制文件
上%%x
循环分配%%x
到所需的扩展。内部xcopy
的输出将采用fullsourcefilename -> fulldestinationfilename
的形式,因此需要使用>
作为分隔符(从文件名到%%a
,以文件名到%%b
)解析。如果%%b
没有设置,那么这是xcopy
的报告(复制了n个文件)的最后一行,需要忽略。 to
和from
文件名需要删除不需要的,但幸运的是恒定的字符串。
有趣的是,在目标文件名已经存在的情况下,似乎没有办法使用xcopy
来抑制提示。
在__XCOPY__命令的两行上,目标路径应该是'“%destdir%\”'在末尾带一个反斜杠,以使__XCOPY__清楚该目标是一个目录而不是一个文件,以避免被问到目标是否是一个文件或一个目录。在这种情况下,也可以使用__XCOPY__选项'/ I'来避免询问目标是文件还是目录。但'/ I'只适用于复制多个文件,而目标结尾的反斜杠也适用于复制单个文件。 – Mofi
使用__XCOPY__将单个(隐藏)文件复制到目标文件夹中具有不同名称的目标文件夹(尚不存在)时,无法避免该提示。我在[BATCH文件要求提供文件或文件夹](http://stackoverflow.com/a/35829012/3074564)中发布了针对此特殊问题的解决方案,因为提示符是语言相关的,并且如果批处理文件应该回答自动提示语言独立。 – Mofi
@mofi:第一个xcopy,授予。第二个 - 不,因为它已经作为一个目录存在。自第一个'xcopy'创建目标以来,目标目录就会存在。似乎(我的解释)'xcopy'的'y'开关不起作用。我想我应该提到M $,但是让它固定下来的机会 - 好吧,我会首先通过玩彩票成为亿万富翁... – Magoo
我很尴尬地问这个用户,有近2,000代表,但是...你能告诉我们你到目前为止尝试过吗? – SomethingDark