0

I would like to create a .bat files that asks for a file extension and a path, then scans the directory and subfolders where the .bat file itself in located looking the all the files with the extension provided and moves them to the specified path while creating a .lnk in the original location.

For example the .bat would behave like this:

Enter file extension: mkv
Enter new path: e:\movies

Then it scans folder and subfolders of where the .bat file is located and move all the .mkv files to the new path, while creating a .lnk in the original source folder for each file that has been moved.

I want to copy also the original source structure to the new one. For example if I have a .mkv file in d:\star trek\movie1\a.mkv I would like to have e:\movies\star trek\movie1\a.mkv and then d:\star trek\movie1\a.lnk. The .lnk should link to the moved file in folder on drive e:.

Any ideas would be highly appreciated.


As a first step, I would like to create a simple batch that asks the user for an extension and then just lists all the files with that extension.

I wrote:

@echo off
set /p type= File type?
dir *.type > list.txt

But that doesn't work. Any suggestions?


I found some code here How to copy a directory structure but only include certain files (using windows batch files) and I'm just learning it. I've wrote down this simple adaptation but I don't understand why the last echo doesn't output what I intend, e.g. the whole destination path and file name. I must be doing something stupid I know!

@echo off
cls

setlocal enabledelayedexpansion
set SOURCE_DIR=K:\source
set DEST_DIR=K:\dest
set FILENAMES_TO_COPY=*.txt

for /R "%SOURCE_DIR%" %%F IN (%FILENAMES_TO_COPY%) do (
    if exist "%%F" (
        echo source: %%F
        set FILE_DIR=%%~dpF
        set FILE_INTERMEDIATE_DIR=!FILE_DIR:%SOURCE_DIR%=!
        set FILE_NAME_EXT=%%~nxF
        set FILE_DIR
        set FILE_INTERMEDIATE_DIR
        set FILE_NAME_EXT
        xcopy /S /I /Y /V "%%F" "%DEST_DIR%!FILE_INTERMEDIATE_DIR!"
        echo destination "%DEST_DIR%!FILE_INTERMEDIATE_DIR%FILE_NAME_EXT!"
        pause
    )
)
Mofi
  • 46,139
  • 17
  • 80
  • 143
Dolphin975
  • 157
  • 2
  • 10

1 Answers1

0

For the batch file below download very small ZIP file Shortcut.zip from Optimum X Downloads - Freeware Utilities, extract the ZIP file to a temporary directory, read file ReadMe.txt of this freeware utility and move Shortcut.exe into same folder as the batch file.

Here is the commented batch code for this task:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
if not exist "%~dp0Shortcut.exe" (
    echo ERROR: Missing Shortcut.exe in "%~dp0".
    goto EndBatch
)

:GetExtension
set "FileExt="
set /P "FileExt=Enter file extension: "
rem Has the user not entered any string?
if not defined FileExt goto GetExtension
rem Remove all double quotes.
set "FileExt=%FileExt:"=%"
rem Is there nothing left after removing double quotes?
if not defined FileExt goto GetExtension
rem Is the first character a dot, then remove it.
if "%FileExt:~0,1%" == "." set "FileExt=%FileExt:~1%"
rem Is there nothing left after removing the dot?
if not defined FileExt goto GetExtension
rem Does the entered file extension string contain a
rem character which is not allowed in a file extension?
set "TempVar="
for /F "eol=| delims=*./:<>?\|" %%I in ("%FileExt%") do set "TempVar=%%I"
if not "%TempVar%" == "%FileExt%" goto GetExtension
rem Don't allow moving *.lnk shortcut files.
if /I "%FileExt%" == "lnk" goto GetExtension


:GetSourcePath
set "SourcePath=%~dp0"
set /P "SourcePath=Enter source path: "
set "SourcePath=%SourcePath:"=%"
if not defined SourcePath goto GetSourcePath
rem Replace all forward slashes by backslashes.
set "SourcePath=%SourcePath:/=\%"
rem Remove a trailing backslash.
if "%SourcePath:~-1%" == "\" set "SourcePath=%SourcePath:~0,-1%"
rem Recreate the environment variable if the entered source directory path
rem was just a backslash to reference root directory of current drive.
if not defined SourcePath set "SourcePath=\"
rem Does the entered source path string contain a
rem character which is not allowed in a folder path?
set "TempVar="
for /F "eol=| delims=*<>?|" %%I in ("%SourcePath%") do set "TempVar=%%I"
if not "%TempVar%" == "%SourcePath%" goto GetSourcePath
rem Determine full qualified source folder path.
for %%I in ("%SourcePath%") do set "SourcePath=%%~fI"
rem Remove once again a trailing backslash which can occur
rem if the source folder is the root folder of a drive.
if "%SourcePath:~-1%" == "\" set "SourcePath=%SourcePath:~0,-1%"
rem The source directory must exist.
if not exist "%SourcePath%\" (
    echo/
    echo ERROR: Source directory "%SourcePath%" does not exist.
    echo/
    goto GetSourcePath
)


:GetTargetPath
set "TargetPath="
set /P "TargetPath=Enter target path: "
if not defined TargetPath goto GetTargetPath
set "TargetPath=%TargetPath:"=%"
if not defined TargetPath goto GetTargetPath
rem Replace all forward slashes by backslashes.
set "TargetPath=%TargetPath:/=\%"
rem Remove a trailing backslash.
if "%TargetPath:~-1%" == "\" set "TargetPath=%TargetPath:~0,-1%"
rem Recreate the environment variable if the entered target directory path
rem was just a backslash to reference root directory of current drive.
if not defined TargetPath set "TargetPath=\"
rem Does the entered target path string contain a
rem character which is not allowed in a folder path?
set "TempVar="
for /F "eol=| delims=*<>?|" %%I in ("%TargetPath%") do set "TempVar=%%I"
if not "%TempVar%" == "%TargetPath%" goto GetTargetPath
rem Determine full qualified target folder path.
for %%I in ("%TargetPath%") do set "TargetPath=%%~fI"
rem Remove once again a trailing backslash which can occur
rem if the target folder is the root folder of a drive.
if "%TargetPath:~-1%" == "\" set "TargetPath=%TargetPath:~0,-1%"
rem Is the target path identical to source folder path?
if /I "%SourcePath%" == "%TargetPath%" (
    echo/
    echo ERROR: Target path cannot be the source path.
    echo/
    goto GetTargetPath
)


rem Does the specified target folder exist?
if exist "%TargetPath%\" goto GetPathLength

rem Ask user if target folder should be created or not.
echo/
echo ERROR: Folder "%TargetPath%" does not exist.
echo/
%SystemRoot%\System32\choice.exe /C YN /N /M "Create path (Y/N)? "
echo/
if errorlevel 2 goto GetTargetPath

md "%TargetPath%" 2>nul
if exist "%TargetPath%\" goto GetPathLength
echo ERROR: Could not create "%TargetPath%".
echo/
goto GetTargetPath


rem Determine length of source path (path of batch file).
:GetPathLength
setlocal EnableDelayedExpansion
set "PathLength=0"
:GetLength
if not "!SourcePath:~%PathLength%!" == "" set /A "PathLength+=1" & goto GetLength
rem For the additional backslash after source folder path.
set /A PathLength+=1
endlocal & set "PathLength=%PathLength%"


rem Move the non-hidden files with matching file extension with exception
rem of the batch file and Shortcut.exe. Use FOR /F with a DIR command line
rem instead of FOR /R to get this code working also on FAT32 and ExFAT
rem drives and when target folder is a subfolder of the batch file.
set "FileCount=0"
for /F "eol=| delims=" %%I in ('dir "%SourcePath%\*.%FileExt%" /A-D-H /B /S 2^>nul') do if /I not "%%I" == "%~f0" if /I not "%%I" == "%~dp0Shortcut.exe" call :MoveFile "%%I"

set "PluralS=s"
if %FileCount% == 1 set "PluralS="
echo Moved %FileCount% file%PluralS%.
goto EndBatch


:MoveFile
rem Do not move a file on which there is already a shortcut file
rem with same file name in source directory because then it would
rem not be possible to create a shortcut file for the moved file.
if exist "%~dpn1.lnk" goto :EOF

rem Get entire path of source file and remove path of batch file.
set "SourceFilePath=%~dp1"
call set "RelativePath=%%SourceFilePath:~%PathLength%%%"

rem Create target file path for this file.
set "TargetFilePath=%TargetPath%\%RelativePath%"
echo TargetFilePath=%TargetFilePath%
rem Remove trailing backslash if there is one.
if "%TargetFilePath:~-1%" == "\" set "TargetFilePath=%TargetFilePath:~0,-1%"

rem Create the target folder independent on its existence
rem and verify if the target folder really exists finally.
md "%TargetFilePath%" 2>nul
if not exist "%TargetFilePath%\" (
    echo ERROR: Could not create folder "%TargetFilePath%".
    goto :EOF
)

rem Move the file to target folder and verify if that was really successful.
rem On error remove a just created target folder not containing a file.
move /Y %1 "%TargetFilePath%\" 2>nul
if errorlevel 1 (
    rd "%TargetFilePath%" 2>nul
    echo ERROR: Could not move file %1.
    goto :EOF
)

rem Create the shortcut file in source directory of moved file.
"%~dp0Shortcut.exe" /F:"%~dpn1.lnk" /A:C /T:"%TargetFilePath%\%~nx1" /W:"%TargetFilePath%" /R:1 >nul
set /A FileCount+=1
goto :EOF


:EndBatch
endlocal
pause

The batch file contains lots of extra code to be fail safe as much as possible against wrong user input.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /?
  • choice /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • md /?
  • move /?
  • rd /?
  • rem /?
  • set /?
  • setlocal /?

See also:

Mofi
  • 46,139
  • 17
  • 80
  • 143
  • What to say... I'm really speechless. This is what I needed and it's coded in a superb way. I'm going to study the batch file, I'm going to learn a lot from it. Mofi, thank you very very very very much. – Dolphin975 Sep 30 '18 at 14:08