gpt4 book ai didi

powershell - 解决带有延迟变量扩展的For循环中 “!”文字问题的解决方法

转载 作者:行者123 更新时间:2023-12-02 23:22:54 25 4
gpt4 key购买 nike

我该如何解决FOR循环?问题在于,对于带有“!”的文件名,DelayedExpansion失败。在他们中

代码(这是更大的脚本的一部分)

:FileScan
::Sets the filenames(in alphabetical order) to variables
SETLOCAL EnableDelayedExpansion
SET "EpCount=0"
FOR /f "Tokens=* Delims=" %%x IN ('Dir /b /o:n %~dp0*.mkv* *.mp4* *.avi* *.flv* 2^>nul') DO (
SET /a "EpCount+=1"
SET Ep!EpCount!=%%x
)
IF %EpCount%==0 ( Echo. & Echo: No Episodes Found & GOTO :Err )

:FolderScan
::Sets the foldernames(in alphabetical order) to variables
SET "FolderCount=0"
FOR /f "Tokens=* Delims=" %%x IN ('Dir /b /o:n /a:d "%~dp0Put_Your_Files_Here" 2^>nul') DO (
SET /a "FolderCount+=1"
SET Folder!FolderCount!=%%x
)

如果无法批量处理,该如何在PowerShell中执行
可以被原始批处理调用的内容,例如:
:FileScan
Call %~dp0FileScanScript.ps1
IF %EpCount%==0 ( Echo. & Echo: No Episodes Found & GOTO :Err )
:FolderScan
Call %~dp0FolderScanScript.ps1

编辑:调用集修复了原始代码,完全避免了DelayedExpansion
SET "EpCount=0"
FOR /f "Tokens=* Delims=" %%x IN ('Dir /b /o:n %~dp0*.mkv* *.mp4* *.avi* *.flv* 2^>nul') DO (
SET /a "EpCount+=1"
CALL SET "Ep%%EpCount%%=%%x"
)

最佳答案

实际上,最简单的解决方案是使用 call set引入另一个解析阶段:

setlocal DisableDelayedExpansion
pushd "%~dp0."
set /A "EpCount=0"
for /F "delims=" %%x in ('
dir /B /A:-D /O:N "*.mkv*" "*.mp4*" "*.avi*" "*.flv*" 2^> nul
') do (
set /A "EpCount+=1"
call set "Ep%%EpCount%%=%%x"
)
popd
endlocal

但是,这会在插入符号 ^出现在字符串或文件名中时引起问题,因为 call在出现引号时会将它们加倍。

要解决此问题,您需要确保在第二个解析阶段也扩展字符串,这可以通过使用临时变量来实现,如下所示:

setlocal DisableDelayedExpansion
pushd "%~dp0."
set /A "EpCount=0"
for /F "delims=" %%x in ('
dir /B /A:-D /O:N "*.mkv*" "*.mp4*" "*.avi*" "*.flv*" 2^> nul
') do (
set "Episode=%%x"
set /A "EpCount+=1"
call set "Ep%%EpCount%%=%%Episode%%"
)
popd
set Ep
endlocal

另外,我在 /A:-D 中添加了过滤器选项 dir以确保没有目录返回。此外,我使用 pushd popd 临时更改为脚本的父目录。编写时, dir命令行在脚本的父目录中搜索了 *.mkv*文件,但在当前工作目录中搜索了所有其他文件,而这可能并不是您想要的。

另一个选项是切换延迟扩展,以便禁用延迟扩展时, for变量引用 %%x会扩展,并且在启用 Ep数组样式变量后会对其进行分配。但是您需要实现一些措施,然后将变量值传输到 endlocal障碍之外,如以下示例所示:

setlocal DisableDelayedExpansion
pushd "%~dp0."
set /A "EpCount=0"
for /F "delims=" %%x in ('
dir /B /A:-D /O:N "*.mkv*" "*.mp4*" "*.avi*" "*.flv*" 2^> nul
') do (
rem /* Delayed expansion is disabled at this point, so expanding
rem the `for` variable reference `%%x` is safe here: */
set "Episode=%%x"
set /A "EpCount+=1"
rem // Enable delayed expansion here:
setlocal EnableDelayedExpansion
rem /* Use a `for /F` loop that iterates once only over the assignment string,
rem which cannot be empty, so the loop always iterates; the expanded value
rem is stored in `%%z`, which must be assigned after `endlocal` in order
rem to have it available afterwards and not to lose exclamation marks: */
for /F "delims=" %%z in ("Ep!EpCount!=!Episode!") do (
endlocal
set "%%z"
)
)
popd
set "Ep"
endlocal

关于powershell - 解决带有延迟变量扩展的For循环中 “!”文字问题的解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45132834/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com