如何通过循环遍历 .txt 中列出的文件,使批处理文件循环从原来的位置恢复?
How to make a batch file loop resume from where it was by looping through the files listed on a .txt?
我想开始将文件夹中的数百个环绕声媒体文件混合成立体声,但这是一个需要花费大量时间的过程。我想创建一个批处理文件,对这组文件(可能在带有 dir /s /b
的 .txt 中列出)执行我的 ffmpeg
命令,只要我的 PC 打开,我就可以 运行 , 但也会记录下一个 运行.
中要排除的已处理文件
我知道我可以通过简单地在我的循环中添加类似 if errorlevel 0 echo "%%~fg">>processed.txt
的东西来轻松跟踪已处理的文件,但我发现想出一种在 [= 时忽略这些文件的方法具有挑战性19=]下次调用脚本。
当然我总是可以手动编辑要循环的文件列表并删除已处理的文件,但我想知道是否有一种聪明的方法可以通过编程来完成
使用日志和 findstr 的示例。将 Set "SourceList=%~dp0list.txt"
的定义替换为用于存储要处理的文件列表的文件的文件路径,或者修改 for /f 循环选项以迭代 Dir
命令的输出。
@Echo off
If not exist "%TEMP%\%~n0.log" break >"%TEMP%\%~n0.log"
Set "SourceList=%~dp0list.txt"
For /f "usebackq delims=" %%G in ("%sourceList%")Do (
%SystemRoot%\System32\Findstr.exe /xlc:"%%G" "%TEMP%\%~n0.log" >nul && (
Rem item already processed and appended to log. do nothing.
) || (
Rem item does not exist in log. Proccess and append to log.
Echo(Proccess %%G
>>"%TEMP%\%~n0.log" Echo(%%G
)
)
我设法产生了一种不依赖外部工具并仅使用 for
循环执行作业的方法。由于需要使用 UTF-8,因此在批处理文件结束后采取了额外的步骤来正确恢复代码页:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=*" %%G in ('%SystemRoot%\System32\chcp.com') do for %%H in (%%G) do set /A "CodePage=%%H" 2>nul
%SystemRoot%\System32\chcp.com 65001 >nul 2>&1
if not exist "%~dpn0.log" break >"%~dpn0.log"
set "FileList=%~dp0FileList.txt"
set "LogFile=%~dpn0.log"
for /f "usebackq delims=" %%G in ("%FileList%") do (
set "SkipFile="
for /f "usebackq delims=" %%H in ("%LogFile%") do (
if "%%G" == "%%H" (
set "SkipFile=1"
)
)
if not defined SkipFile (
echo --^> Processing file "%%~nG"
rem file is processed
) else (
echo "%%~nG" has already been processed
rem file is not processed
)
)
%SystemRoot%\System32\chcp.com %CodePage% >nul
endlocal
可以看出,这个回答有一部分是受@T3RROR的启发!
我想开始将文件夹中的数百个环绕声媒体文件混合成立体声,但这是一个需要花费大量时间的过程。我想创建一个批处理文件,对这组文件(可能在带有 dir /s /b
的 .txt 中列出)执行我的 ffmpeg
命令,只要我的 PC 打开,我就可以 运行 , 但也会记录下一个 运行.
我知道我可以通过简单地在我的循环中添加类似 if errorlevel 0 echo "%%~fg">>processed.txt
的东西来轻松跟踪已处理的文件,但我发现想出一种在 [= 时忽略这些文件的方法具有挑战性19=]下次调用脚本。
当然我总是可以手动编辑要循环的文件列表并删除已处理的文件,但我想知道是否有一种聪明的方法可以通过编程来完成
使用日志和 findstr 的示例。将 Set "SourceList=%~dp0list.txt"
的定义替换为用于存储要处理的文件列表的文件的文件路径,或者修改 for /f 循环选项以迭代 Dir
命令的输出。
@Echo off
If not exist "%TEMP%\%~n0.log" break >"%TEMP%\%~n0.log"
Set "SourceList=%~dp0list.txt"
For /f "usebackq delims=" %%G in ("%sourceList%")Do (
%SystemRoot%\System32\Findstr.exe /xlc:"%%G" "%TEMP%\%~n0.log" >nul && (
Rem item already processed and appended to log. do nothing.
) || (
Rem item does not exist in log. Proccess and append to log.
Echo(Proccess %%G
>>"%TEMP%\%~n0.log" Echo(%%G
)
)
我设法产生了一种不依赖外部工具并仅使用 for
循环执行作业的方法。由于需要使用 UTF-8,因此在批处理文件结束后采取了额外的步骤来正确恢复代码页:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=*" %%G in ('%SystemRoot%\System32\chcp.com') do for %%H in (%%G) do set /A "CodePage=%%H" 2>nul
%SystemRoot%\System32\chcp.com 65001 >nul 2>&1
if not exist "%~dpn0.log" break >"%~dpn0.log"
set "FileList=%~dp0FileList.txt"
set "LogFile=%~dpn0.log"
for /f "usebackq delims=" %%G in ("%FileList%") do (
set "SkipFile="
for /f "usebackq delims=" %%H in ("%LogFile%") do (
if "%%G" == "%%H" (
set "SkipFile=1"
)
)
if not defined SkipFile (
echo --^> Processing file "%%~nG"
rem file is processed
) else (
echo "%%~nG" has already been processed
rem file is not processed
)
)
%SystemRoot%\System32\chcp.com %CodePage% >nul
endlocal
可以看出,这个回答有一部分是受@T3RROR的启发!