最近出现了一个问题,即将用户预定义文件类型扩展名的许多文件从一个文件夹移动到许多不同的文件夹,这些文件夹立即在文件名称内的密钥字符串(YEAR)上创建。此外,当移动到新创建的文件夹时,应保存文件而不使用用户预定义的文件类型扩展名(文件名2016.myextension.txt
>文件名2016.txt
)。我一直对这个问题感兴趣,所以我创建了简单的cmd程序。
有两个问题:
程序运行正常,但速度太慢。
有没有办法让它跑得更快?
ECHO %TIME%
循环中的for /l %%A in (1900,1,2099)
命令,查看程序代码的结尾,始终返回相同的时间值。
有没有办法让它返回正确的当前系统时间?
以下是程序代码:
rem program start
rem
rem use double % for cmd line parameters when generating .bat
rem use single % for cmd line parameters for direct cmd execution
rem use ^ for cmd line brake
rem
rem
rem change command prompt attributes
rem
echo off
mode con:cols=80 lines=40
title Program
color 0A
cls
echo.
echo Program start running at... %TIME%
echo.
rem set local variables value
setlocal EnableDelayedExpansion EnableExtensions
set old_folder_path=C:\Torrent_files\
set new_folder_path=C:\Torrent_movies\
set folder_path=C:\Torrent_movies\Year_
set f1=.
set f2=.
set list_path_extension=C:\Torrent_movies\Torrent_list.txt
set extension=.torrent
rem create root folder for new movie folders
if not exist %new_folder_path% (echo Creating Torrent_movies folder... && ^
md %new_folder_path% && echo Done at... %TIME%)
echo.
rem set current directory to new_folder_path
cd %new_folder_path%
rem create new list
rem of torrent files inside the folder
echo Creating empty List of files...
echo. > %list_path_extension%
echo Done at... %TIME%
echo.
rem Fill List of files
echo Filling List with file names...
for /r %old_folder_path% %%T in (*%extension%) do (^
set f1=%%T && ^
set f2=!f1:%old_folder_path%=! && ^
echo !f2! >> %list_path_extension%)
echo Done at... %TIME%
echo.
rem search for year inside file paths saved in Torrent_list.txt file
rem by using for loop, where value of cmd parameter
rem A goes from year 1900 up to 2099,
rem if there is match between string value of A as a regular expression,
rem and string inside file path, create new folder for that year
rem else skip
echo Moving files
for /l %%A in (1900,1,2099) do (^
for /f "tokens=*" %%G in ('findstr /r "\<%%A" %list_path_extension%') do (^
(if exist %folder_path%%%A (echo.) ^
else (md %folder_path%%%A && echo %folder_path%%%A Folder created)) && ^
echo Moving file %%G && set f1=%%G && set f2=!f1:%extension%=! && ^
move "%old_folder_path%%%G" "%folder_path%%%A\!f2!" && echo Done at... %TIME% && echo.))
rem list current directory to show changes
dir %new_folder_path%
echo.
echo Program finished at...%TIME%
echo.
pause
rem program end
根据我的问题给出的所有答案,我已经完成了这个程序,完全解决了这个问题。欢迎任何改进建议。
@echo off
rem
rem Program solves next problem :
rem
rem Inside one folder there are many files.
rem Files have different file type.
rem File name can contain :
rem only one or none, YYYY (year) string,
rem key word or user predefined file type
rem
rem exmpl :
rem
rem Root folder path :
rem
rem C:\My_files_type_of_backup
rem
rem Folder contains :
rem
rem File 1 video (1998).backup.avi
rem File 2 painting 2016.backup.bmp
rem File 3 mp3 1901.backup.wav
rem File 4 My Bigraphy 2000.backup.txt
rem File 5 mp4 19.wav
rem File 6 My file 2000.txt
rem File 7 List of files.rtf
rem
rem Program must select all files which names contains
rem YYYY string, year from 1900-2099 and
rem selected key word,
rem or user predefined file type entered by keyboard and
rem selected file type extension entered by keyboard
rem
rem Program then creates new folders
rem with YYYY string inside folder name and
rem moves files to newly created folders
rem according to year inside file name
rem
rem Depending on the options selected
rem at the beginning of the program,
rem program moves only files that
rem have selected key word inside file name and
rem key word can be deleted from
rem file name before moving
rem After program execution this would be result :
rem
rem options selected :
rem
rem key_word = .backup,
rem erase key word = Yes
rem file type = .*
rem
rem Root folder path :
rem
rem C:\My_files_type_of_backup
rem
rem Folder contains new folders with files in it:
rem
rem Year 1901
rem File 3 mp3 1901.wav
rem Year 1998
rem File 1 video (1998).avi
rem Year 2000
rem File 4 My Bigraphy 2000.txt
rem File 6 My file 2000.txt
rem Year 2016
rem File 2 painting 2016.bmp
rem
rem File 5 mp4 19.wav
rem File 7 List of files.rtf
rem
rem
rem
rem CMD attributes
rem
mode con:cols=80 lines=40
title Program move files
color 0A
cls
echo.
echo Program started at ... %TIME%
rem
rem Local variables
rem
setlocal enableextensions enabledelayedexpansion
set f=0
set f1=.
set f2=.
rem
rem Program options
rem
set /p key_word=Please enter key word [exmpl .backup] : || set key_word=*
echo.
echo Selected key word : %key_word%
echo.
set /p erase=Do You wish to erase key word from file name [Enter=No]: || set erase=n
echo.
set /p file_type=Please enter file type exmpl .* or .bmp : || set file_type=.*
echo.
echo Selected file type : %file_type%
echo.
rem
rem Find all files inside folder that contains
rem YYYY string (year 1900-2099) and
rem selected key word inside file name
rem
for %%# in (*%key_word%*%file_type%) do (
for /f "tokens=1-26 delims=0123456789 " %%a in ("%%~n#") do (
set "delims=%%a%%b%%c%%d%%e%%f%%g%%h%%i%%j%%k%%l%%m%%n%%o%%p%%q%%r%%s%%t%%u%%v%%w%%x%%y%%z"
call :extractYear && (
for %%y in ("!year!") do (
rem Create new folder
if not exist "%%~y\" md "Year %%~y"
rem Erase selected key word from file name
rem if erase option is set to 'Yes' and
rem key word is not empty string
rem
set f1=%%~#
set f2=!f1!
if %erase% neq n if %key_word% neq * (set f2=!f1:%key_word%=!)
rem
rem Move file
rem
echo Moving "!f1!" to folder "Year %%~y\!f2!"
move "!f1!" "Year %%~y\!f2!"
rem count number of moved files
set /a f=f+1
)
)
)
)
echo.
if %f% equ 0 (echo There are no files that match criteria for moving) else (echo %f% files moved)
echo.
echo Program finished at ... %TIME%
pause
goto :eof
:extractYear
for %%a in ("") do for /f "tokens=1-26 delims=%delims% " %%a in ("%%~n#") do for %%# in (
%%~z %%~y %%~x %%~w %%~v %%~u %%~t %%~s %%~r %%~q %%~p %%~o %%~n
%%~m %%~l %%~k %%~j %%~i %%~h %%~g %%~f %%~e %%~d %%~c %%~b %%~a
) do if %%~# geq 1900 if %%~# leq 2099 (
set "year=%%~#"
exit /b 0
)
exit /b 1
答案 0 :(得分:1)
看起来你正在运行findstr 199次。我希望通过删除for / l循环并使用单个findstr实例来提高速度 也许:
findstr /r "\<19[0-9][0-9] \<20[0-9][0-9]"
答案 1 :(得分:1)
尝试避免调用findstr
只是另一个想法。虽然不是防弹的(仅针对洪流电影网站中前几页的列表进行测试),但这可以在合理的时间内完成任务。
主要思想是从文件名中删除数字(在for /f
循环中使用它们作为分隔符),并将其余字符用作另一个for /f
中的分隔符,只留下数字文件名。然后迭代该组数字以确定它们是否匹配所需的年份范围。如果找到一年,则脚本将回显以控制move
命令执行。如果输出正确,请移除echo
以执行move
操作。
@echo off
setlocal enableextensions disabledelayedexpansion
for %%# in (*.torrent) do (
for /f "tokens=1-26 delims=0123456789 " %%a in ("%%~n#") do (
set "delims=%%a%%b%%c%%d%%e%%f%%g%%h%%i%%j%%k%%l%%m%%n%%o%%p%%q%%r%%s%%t%%u%%v%%w%%x%%y%%z"
call :extractYear && (
setlocal enabledelayedexpansion
for %%y in ("!year!") do (
endlocal
if not exist "%%~y\" md "%%~y"
echo move "%%~#" "%%~y"
)
)
)
)
goto :eof
:extractYear
for %%a in ("") do for /f "tokens=1-26 delims=%delims% " %%a in ("%%~n#") do for %%# in (
%%~z %%~y %%~x %%~w %%~v %%~u %%~t %%~s %%~r %%~q %%~p %%~o %%~n
%%~m %%~l %%~k %%~j %%~i %%~h %%~g %%~f %%~e %%~d %%~c %%~b %%~a
) do if %%~# geq 1900 if %%~# leq 2016 (
set "year=%%~#"
exit /b 0
)
exit /b 1
答案 2 :(得分:1)
简而言之,您必须在程序开头(或至少在循环之前)编写setlocal enabledelayedexpansion
并使用!TIME!
代替%TIME%
来打印当前值而不是循环开始时的值。