首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将视频文件从Pictures目录移动到视频目录

将视频文件从Pictures目录移动到视频目录
EN

Stack Overflow用户
提问于 2017-02-21 04:45:10
回答 2查看 1.2K关注 0票数 0

我的照片导入工具(Picasa)在从我的手机和相机导入照片和视频方面做得很好。我喜欢的是,它根据每一张照片/视频的拍摄日期在Pictures目录下创建一个子文件夹。所以你最终得到了这样的结构:

代码语言:javascript
复制
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:\图片目录移到C:\视频目录,但也使用date子文件夹.即

代码语言:javascript
复制
Move C:\Pictures\2017-02-01\DSC_0003.mp4 to C:\Videos\2017-02-01\DSC_0003.mp4

注意,date子文件夹可能存在于C:\视频下,也可能不存在。

另外,由于这些都是大的视频文件,而且有很多这样的文件,所以我更喜欢一个实际进行移动而不是复制然后删除的过程,为了速度和磁盘空间的利用,因为我几乎没有空间(在重新组织这些文件之后,我将被归档到NAS)。

还喜欢使用RoboCopy、xcopy或xxcopy,因为我有它们,并且今天在我的机器上使用它们。如果在很大程度上更容易使用PowerShell脚本,我可以了解它是否容易做到。

最终解决方案--我使用了莫菲的答案,但只做了一点改进,添加了一个函数来计算目录字符串长度

代码语言:javascript
复制
@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
)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-21 07:56:55

下面是一个注释的批处理代码,用于此文件移动任务,并保持目录结构。

代码语言:javascript
复制
@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 /?

还可以阅读微软关于使用命令重定向运算符的文章,了解>nul2>nul的解释。在主FOR循环中,重定向操作符>通过插入字符^转义,在解析命令行的时被解释为文字字符,在FOR执行DIR命令行时被解释为重定向操作符。

票数 2
EN

Stack Overflow用户

发布于 2017-02-21 07:32:25

代码语言:javascript
复制
@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

您需要更改sourcedirdestdir的设置,以适应您的情况。

所需的移动命令仅仅是为测试目的而编写的ECHO在验证命令是正确的之后,将ECHO(MOVE更改为MOVE以实际移动文件。附加>nul以抑制报告消息(例如。1 file moved)

第一个xcopy创建所需的子树,第二个使用/L选项来列出而不是复制文件。

%%x上的循环将%%x分配给所需的扩展。内部xcopy的输出将是表单fullsourcefilename -> fulldestinationfilename,因此需要使用>作为分隔符进行解析,从-filename到%%a,从-filename到%%b。如果没有设置%%b,那么这是xcopy报告(复制的n个文件)的最后一行,需要忽略它。tofrom文件名需要修剪掉不需要的字符串,但幸运的是,字符串是不变的。

有趣的是,在目标文件名已经存在的情况下,似乎无法使用xcopy来抑制提示。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42358878

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档