gpt4 book ai didi

for-loop - 如何使用 ! 处理路径名在 for/F 循环中?

转载 作者:行者123 更新时间:2023-12-05 03:24:55 25 4
gpt4 key购买 nike

在一个复杂的批处理文件中,我想读入带有路径的文件,除其他外,将它们一个接一个地读入一个变量中,用空格分隔。

到目前为止,这与以下代码配合使用效果很好 - 但前提是路径不包含感叹号。

即使使用 setlocal 命令(enabledelayedexpansion/disabledelayedexpansion)我也没有成功处理感叹号。

这里有没有人对这个问题有聪明的想法?

以下示例批处理在当前目录中创建一个文本文件,然后在 for/F 循环中读取它。最后,文本文件中的所有三个路径都应位于变量 %Output% 中。但是带有感叹号。

@echo off

setlocal enabledelayedexpansion

echo This is an example^^! > "textfile.txt"
echo This is a second example^^! >> "textfile.txt"
echo And this line have an ^^! exclamation mark in the middle >> "textfile.txt"

for /F "usebackq tokens=* delims=" %%a in (textfile.txt) do (
set "Record=%%a"
set "Output=!Output!!Record! - "
)
)

echo %Output%
echo !Output!

endlocal

输出是这样的:

This is an example  - This is a second example  - And this line have an  exclamation mark in the middle

但应该是这样的:

This is an example!  - This is a second example!  - And this line have an ! exclamation mark in the middle

最佳答案

建议不要对处理文件和目录、文本文件中的行、批处理文件本身未定义的字符串或从程序或命令行的执行中捕获的输出使用延迟变量扩展。如果由于某些原因需要在 FOR 循环中使用延迟变量扩展,则应首先将要处理的文件/目录名称、行或字符串分配给环境变量,同时延迟扩展被禁用,然后在 FOR 循环中临时启用延迟扩展。

这是一个批处理文件演示,可以在命令提示符窗口中简单地运行或双击批处理文件。它在临时文件目录中创建了几个用于演示的文件,但在退出前将它们全部删除。

@echo off
setlocal EnableExtensions DisableDelayedExpansion

echo This is an example!> "%TEMP%\TextFile.tmp"
echo This is a second example!>> "%TEMP%\TextFile.tmp"
echo And this line has an exclamation mark ! in the middle.>> "%TEMP%\TextFile.tmp"

set "Output="
(for /F usebackq^ delims^=^ eol^= %%I in ("%TEMP%\TextFile.tmp") do set "Line=%%I" & call :ConcatenateLines) & goto ContinueDemo
:ConcatenateLines
set "Output=%Output% - %Line%" & goto :EOF

:ContinueDemo
cls
echo/
echo All lines concatenated are:
echo/
echo %Output:~3%
set "Output="
del "%TEMP%\TextFile.tmp"

echo File with name ".Linux hidden file!">"%TEMP%\.Linux hidden file!"
echo File with name "A simple test!">"%TEMP%\A simple test!"
echo File with name " 100%% Development & 'Test' (!).tmp">"%TEMP%\ 100%% Development & 'Test(!)'.tmp"
echo/
echo Files with ! are:
echo/
for /F "eol=| tokens=* delims=" %%I in ('dir "%TEMP%\*!*" /A-D /B /ON 2^>nul') do (
set "NameFile=%%I"
set "FileName=%%~nI"
set "FileExtension=%%~xI"
set "FullName=%TEMP%\%%I"
setlocal EnableDelayedExpansion
if defined FileName (
if defined FileExtension (
echo File with ext. !FileExtension:~1!: !NameFile!
) else (
echo Extensionless file: !NameFile!
)
) else echo Extensionless file: !NameFile!
del "!FullName!"
endlocal
)
endlocal
echo/
@setlocal EnableExtensions EnableDelayedExpansion & for /F "tokens=1,2" %%G in ("!CMDCMDLINE!") do @endlocal & if /I "%%~nG" == "cmd" if /I "%%~H" == "/c" set /P "=Press any key to exit the demo . . . "<nul & pause >nul

这个批处理文件的输出是:

All lines concatenated are:

This is an example! - This is a second example! - And this line has an exclamation mark ! in the middle.

Files with ! are:

File with ext. tmp: 100% Development & 'Test(!)'.tmp
Extensionless file: .Linux hidden file!
Extensionless file: A simple test!

带有连接行的文本文件示例使用了从 FOR 循环中调用的子例程来处理文本文件中的行。此处使用的语法是通过使子例程尽可能接近 FOR 命令行来获得最佳性能。如果 FOR 循环必须处理数百甚至数千个项目,这一点很重要。

在将当前处理文件的所有部分分配给环境变量后,示例处理文件名启用和禁用 FOR 循环内的延迟扩展。在处理数千个文件之前减少环境变量列表对于使用此方法获得更好的性能可能很有用。

Magoo´s answer 中显示了另一种方法,使用命令 CALL 获取带有引用环境变量的命令行(重新)定义在第二次解析的循环中。我过去也经常使用这种方法,但不要再使用这种方法了,因为它既不安全又效率低下。 call set 导致 cmd.exe 在当前目录和下一个环境变量 PATH 的所有目录中搜索名称为 的文件设置 和环境变量PATHEXT 的文件扩展名。因此,它会在 FOR 循环的每次迭代中导致在后台进行大量文件系统访问,如果偶然出现文件 set.exeset。 batset.cmd 等被 cmd.exe 某处发现,由于运行可执行文件或调用批处理文件而不是环境变量的(重新)定义。

我写的以下答案也可能有帮助:

关于for-loop - 如何使用 ! 处理路径名在 for/F 循环中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72155863/

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