为什么不打印带问号的字符串(从命令提示符开始)?
代码示例:
FOR %A IN (--eval string?) DO ECHO %A
代码仅打印--eval
但忽略string?
是否有解决方法来打印它?
我试过:
"string?"
"string^?"
或"string^^^?"
与bang !
??
似乎没什么用。这似乎是一个错误。
编辑根据评论时的答案和问题。
我期待什么? 我希望有两个选项--eval string?打印。
我想要实现的目标? 我试图简化我的最终目标。
最后,我希望!temp_string!
变量中包含两个字符串(在下面的test.bat
示例中)。
基于真实代码的示例:
test.bat
示例:
@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
ECHO "First argument outside FOR statement: %~1"
ECHO "Second argument outside FOR statement: %~2"
FOR %%A IN (%*) DO (
ECHO "First inside FOR argument: %~1"
ECHO "Second inside FOR argument: %~2"
SET "temp_string=%%~A"
ECHO !temp_string!
)
如果执行text.bat而没有问题?
,请执行以下操作:
test.bat --eval --test
它会正确显示两个字符串。
结果:
"First argument outside FOR statement: --eval"
"Second argument outside FOR statement: --test"
"First inside FOR argument: --eval"
"Second inside FOR argument: --test"
--eval
"First inside FOR argument: --eval"
"Second inside FOR argument: --test"
--test
但是,如果使用相同的参数运行它,但包含?
test.bat --eval --test?
结果不正确:
"First argument outside FOR statement: --eval"
"Second argument outside FOR statement: --test?"
"First inside FOR argument: --eval"
"Second inside FOR argument: --test?"
--eval
如果您希望看到真实的代码,这是简化的,您可以在第783行找到它here。
第二次修改
我现在正试图从@dbenham的拟议解决方案中获取%%A
的值。
%test%
变量在两种情况下仍为空:
@echo off
setlocal disableDelayedExpansion
set "string=--eval string? ;hello <&|>! "^<^&^|^>!""
set string
echo(
setlocal enableDelayedExpansion
for %%n in (^"^
%= This results in a quoted newline character =%
^") do for /f delims^=^ eol^= %%A in ("!string: =%%~n!") do (
if "!!" equ "" endlocal set "test=%%~A"
echo "A value:" %%A
echo "Test value:" %test%
)
echo %test%
输出:
string=--eval string? ;hello <&|>! "<&|>!"
"A value:" --eval
"Test value:"
"A value:" string?
"Test value:"
"A value:" ;hello
"Test value:"
"A value:" <&|>!
"Test value:"
"A value:" "<&|>!"
"Test value:"
ECHO is off.
第三和第四编辑 - 答案。
基于dbenham&amp;&amp;斯蒂芬我正在发布我满意的工作代码。
注意:dbenham肮脏的"^<^&^|^>!"
在这里不起作用,但我认为我不需要它。
@echo off
REM works for all!!! --> *.bat -string? :hello "<&|>!"
setlocal disableDelayedExpansion
:process_arguments
:: Process all arguments in the order received
if defined %1 (
ECHO %1
SET "string=%string% %~1"
shift
goto:process_arguments
)
echo(
setlocal enableDelayedExpansion
for %%n in (^"^
%= This results in a quoted newline character =%
^") do for /f "eol= delims=" %%A in ("!string: =%%~n!") do (
if "!!" equ "" endlocal
set "test=%%~A"
echo "In for loop - a value: %%A"
CALL :testing_value "%%A"
)
:: END
goto :eof
:: echo "Outside test:" %test%
setlocal disableDelayedExpansion
:testing_value
set "test=%~1"
set test
echo "Calling Subroutine: %test%"
echo:
谢谢你的指导!
答案 0 :(得分:3)
for
会尝试查找匹配的文件。并且?
恰好是“一个字符”的通配符。也许,你没有匹配的文件...
要处理此类字符串,请使用for /f
:
FOR /f "delims=" %A IN ("--eval string?") DO ECHO %A
编辑找到了一种拆分方法,但是有一个临时文件:
@echo off
setlocal enabledelayedexpansion
REM create a linefeed:
set ^"LF=^
^" The above empty line is critical - DO NOT REMOVE
set "string=--eval string? hello"
(echo %string: =!LF!%) >tmp
for /f "delims=" %%A in (tmp) do echo %%A
Edit2 dbenham向我展示了一种没有临时文件的方法(有时候我会考虑过多的角落):
@echo off
setlocal enabledelayedexpansion
REM create a linefeed:
set ^"LF=^
^" The above empty line is critical - DO NOT REMOVE
set "string=--eval string? hello"
for /f "delims=" %%A in ("%string: =!LF!%") do echo %%A
答案 1 :(得分:3)
Stephan's last answer有效,但可能会出现并发症:
!
文字出现问题。
<LF>
替换术语的FOR变量这是一种可以解决所有问题的强大技术:
@echo off
setlocal disableDelayedExpansion
set "string=--eval string? ;hello <&|>! "^<^&^|^>!""
set string
echo(
setlocal enableDelayedExpansion
for %%n in (^"^
%= This results in a quoted newline character =%
^") do for /f delims^=^ eol^= %%A in ("!string: =%%~n!") do (
if "!!" equ "" endlocal
echo %%A
)
- 输出 -
string=--eval string? ;hello <&|>! "<&|>!"
--eval
string?
;hello
<&|>!
"<&|>!"
<强> 修改 强>
由于我们用[LF]替换了所有[space],我们知道一条线永远不能以[space]开头。
因此,如果我们将EOL设置为[space],则更简单。 FOR / F选项可简化为:
for /f "eol= delims=" ...
答案 2 :(得分:1)
使用标签并移动参数的循环可以处理?
作为文字。
要防止转移主脚本参数,请调用标签,例如:args below。
@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
CALL :args %*
ECHO "First outside argument: %~1"
ECHO "Second outside argument: %~2"
GOTO :eof
:args
ECHO "First inside argument: %~1"
ECHO "Second inside argument: %~2"
:args_loop
SET "temp_string=%~1"
IF NOT DEFINED temp_string GOTO :end_args_loop
ECHO !temp_string!
SHIFT
GOTO :args_loop
:end_args_loop
SET "temp_string="
GOTO :eof
一个已知问题是%*
中有/?
,call
可能会输出call
的帮助。