2017-02-21 2 views
0

Инструмент для импорта фотографий (Picasa) отлично справляется с импортированием фотографий и видео с телефона и камеры. Мне нравится, что он создает подпапку под каталогом Pictures, основанную на Photo Taken Date каждой фотографии/видео. Таким образом, вы получаете в итоге эту структуру:Переместить видеофайлы из каталога «Изображения» в каталог видео

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, я могу узнать, что это легко сделать.

Окончательное решение Я использовал ответ MOFI, но повысить его только немного, чтобы добавить функцию для вычисления длины строки каталога

@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 
) 
+0

Я смущен, чтобы спросить об этом пользователя, у которого есть почти 2 000 представителей, но ... не могли бы вы показать нам, что вы пробовали до сих пор? – SomethingDark

ответ

2

Вот комментированный пакетный код для этой движущейся задачи с сохранением структуры каталогов.

@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 /?

Читайте также статью Microsoft о Using Command Redirection Operators для объяснения >nul и 2>nul. В главном ДЛЯ цикла оператор перенаправления > экранируются с характером ^ каретки следует интерпретировать как буквенный символ на разбор ДЛЯ командной строки, а затем как перенаправления оператора на выполнении DIR командной строки ДЛЯ.

+0

работал как шарм и приятная функция для удаления пустых исходных каталогов !!! Плюс отличная документация на код! Я немного упростил ваше решение, чтобы иметь функцию для вычисления длины каталога исходной папки, чтобы она не была жестко запрограммирована в случае, если я хочу использовать это как базовую линию для других задач позже. См. Мой последний ответ, обновленный в исходном вопросе. –

0
@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 ed для целей тестирования. После того, как вы подтвердили правильность команд, измените значение ECHO(MOVE на MOVE, чтобы фактически переместить файлы. Append >nul подавить сообщения отчета (например. 1 file moved)

Первый xcopy создает необходимые поддеревья, второй использует параметр /L в список, а не копировать файлы

Петля на %%x назначает %%x к требуемым расширениям , Выходной сигнал от внутреннего xcopy будет иметь вид fullsourcefilename -> fulldestinationfilename, поэтому его необходимо проанализировать с использованием > в качестве разделителя, от -файла до %%a, от-файла до %%b. Если %%b не задано, это последняя строка отчета xcopy (n файлов скопировано), которые необходимо игнорировать. Имена файлов to и from должны быть обрезаны нежелательными, но, к счастью, постоянными символьными строками.

Интересно, что, как представляется, нет способа использовать xcopy для подавления запроса в случае, когда имя файла назначения уже существует.

+0

В обеих строках с командой __XCOPY__ целевой путь должен быть ''% destdir% \ "' с обратной косой чертой в конце, чтобы очистить для __XCOPY__ то, что цель - это каталог, а не файл, чтобы избежать запроса, является ли цель файлом или каталог. В этом случае также использование опции __XCOPY__ '/ I' позволит избежать запроса, является ли цель файлом или каталогом. Но '/ I' работает только при копировании нескольких файлов, в то время как обратная косая черта в конце цели также работает при копировании одного файла. – Mofi

+0

Невозможно избежать подсказки при использовании __XCOPY__ для копирования одного (скрытого) файла в целевую папку (еще не существующую) с другим именем в целевой папке. Я опубликовал в [файле BATCH файл или папку] (http://stackoverflow.com/a/35829012/3074564) решение для этой специальной проблемы, поскольку приглашение зависит от языка и требует дополнительного кода, если пакетный файл должен ответить на подсказка автоматически независима от языка. – Mofi

+0

@mofi: первый xcopy, предоставлен. Второй - нет, поскольку он уже будет существовать как каталог. Целевой каталог будет существовать с момента его создания. Похоже, что (моя интерпретация) переключатель 'y' для' xcopy' не работает. Я полагаю, что я должен упомянуть о M $, но шансы на его исправление - ну, я был бы миллиардером, играя сначала в лотерею ... – Magoo

Смежные вопросы