如何根据用户输入的文件扩展名将某些文件移动到另一个文件夹并在原始目录中为每个移动的文件创建快捷方式?
How to move certain files based on user input file extension to another folder and create shortcuts in original directory for each moved file?
我想创建一个要求文件扩展名和路径的 .bat 文件,然后扫描 .bat 文件本身所在的目录和子文件夹,查找具有提供的扩展名的所有文件并移动它们到指定路径,同时在原始位置创建 .lnk。
例如 .bat 的行为如下:
输入文件扩展名:mkv
输入新路径:e:\movies
然后它会扫描 .bat 文件所在的文件夹和子文件夹,并将所有 .mkv 文件移动到新路径,同时在原始源文件夹中为每个已移动的文件创建一个 .lnk。
我也想将原始源结构复制到新结构。例如,如果我在 d:\star trek\movie1\a.mkv
中有一个 .mkv
文件,我希望有 e:\movies\star trek\movie1\a.mkv
,然后是 d:\star trek\movie1\a.lnk
。 .lnk
应该 link 移动到驱动器 e:
文件夹中的文件。
如有任何想法,我们将不胜感激。
作为第一步,我想创建一个简单的批处理,要求用户提供扩展名,然后只列出具有该扩展名的所有文件。
我写了:
@echo off
set /p type= File type?
dir *.type > list.txt
但这不起作用。有什么建议吗?
我在这里找到了一些代码 How to copy a directory structure but only include certain files (using windows batch files),我正在学习它。我已经写下了这个简单的改编,但我不明白为什么最后一个回声没有输出我想要的,例如整个目标路径和文件名。我一定是在做一些我知道的蠢事!
@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
)
)
对于下面的批处理文件,从 Optimum X Downloads - Freeware Utilities 下载非常小的 ZIP 文件 Shortcut.zip,将 ZIP 文件解压到一个临时目录,读取文件 ReadMe.txt
并将 Shortcut.exe
移动到与批处理文件相同的文件夹中。
这里是这个任务的批处理代码:
@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
批处理文件包含大量额外代码,以尽可能防止错误的用户输入。
要了解使用的命令及其工作原理,请打开命令提示符 window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
call /?
choice /?
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
md /?
move /?
rd /?
rem /?
set /?
setlocal /?
另请参阅:
- What does %~dp0 mean, and how does it work?
- 关于 Using command redirection operators
的 Microsoft 文章
- Single line with multiple commands using Windows batch file
- How does the Windows Command Interpreter (CMD.EXE) parse scripts?
- Why is no string output with 'echo %var%' after using 'set var = text' on command line?
我想创建一个要求文件扩展名和路径的 .bat 文件,然后扫描 .bat 文件本身所在的目录和子文件夹,查找具有提供的扩展名的所有文件并移动它们到指定路径,同时在原始位置创建 .lnk。
例如 .bat 的行为如下:
输入文件扩展名:mkv
输入新路径:e:\movies
然后它会扫描 .bat 文件所在的文件夹和子文件夹,并将所有 .mkv 文件移动到新路径,同时在原始源文件夹中为每个已移动的文件创建一个 .lnk。
我也想将原始源结构复制到新结构。例如,如果我在 d:\star trek\movie1\a.mkv
中有一个 .mkv
文件,我希望有 e:\movies\star trek\movie1\a.mkv
,然后是 d:\star trek\movie1\a.lnk
。 .lnk
应该 link 移动到驱动器 e:
文件夹中的文件。
如有任何想法,我们将不胜感激。
作为第一步,我想创建一个简单的批处理,要求用户提供扩展名,然后只列出具有该扩展名的所有文件。
我写了:
@echo off
set /p type= File type?
dir *.type > list.txt
但这不起作用。有什么建议吗?
我在这里找到了一些代码 How to copy a directory structure but only include certain files (using windows batch files),我正在学习它。我已经写下了这个简单的改编,但我不明白为什么最后一个回声没有输出我想要的,例如整个目标路径和文件名。我一定是在做一些我知道的蠢事!
@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
)
)
对于下面的批处理文件,从 Optimum X Downloads - Freeware Utilities 下载非常小的 ZIP 文件 Shortcut.zip,将 ZIP 文件解压到一个临时目录,读取文件 ReadMe.txt
并将 Shortcut.exe
移动到与批处理文件相同的文件夹中。
这里是这个任务的批处理代码:
@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
批处理文件包含大量额外代码,以尽可能防止错误的用户输入。
要了解使用的命令及其工作原理,请打开命令提示符 window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
call /?
choice /?
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
md /?
move /?
rd /?
rem /?
set /?
setlocal /?
另请参阅:
- What does %~dp0 mean, and how does it work?
- 关于 Using command redirection operators 的 Microsoft 文章
- Single line with multiple commands using Windows batch file
- How does the Windows Command Interpreter (CMD.EXE) parse scripts?
- Why is no string output with 'echo %var%' after using 'set var = text' on command line?