我刚刚意识到我在启动时在这个注册表项处执行了一个 bat 文件,里面有echo running abc
一些其他不相关的东西
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun
所以在这里我修改了那个 bat 文件...它只有一行,其中没有任何不相关的内容。
您会看到该 bat 文件的内容。
下面是 cmd 提示符的一些输出,显示了当前的情况,这是相同的基本问题,但您应该能够重现该问题
现在的问题是,
- 为什么说的是 echo sss 而不是 echo sss ttt?
- 如何使用 FOR 抑制 cmd 或初始化 bat 文件的运行?FOR 语句实际上应该只显示“echo g”,而不是“echo sss”或“echo sss ttt”。
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
sss ttt
C:\Documents and Settings\Administrator>cd\
C:\>type \blah\startfile.bat <ENTER>
@echo sss ttt
C:\>
C:\>for /f %f in ('echo g ^| findstr "g"') do echo %f <ENTER>
C:\>echo sss
sss
C:\>echo g
g
C:\>
答案1
为什么说的是 echo sss 而不是 echo sss ttt?
因为该行sss ttt
包含空格字符。该for
命令将其标记化,并将前半部分存储sss
在变量中%f
,将后半部分存储ttt
在%g
变量中。
如何使用 FOR 抑制 cmd 或初始化 bat 文件的运行?FOR 语句实际上应该只显示“echo g”,而不是“echo sss”或“echo sss ttt”。
似乎为了评估echo g ^| findstr "g"
新的命令解释器被初始化并且你的\blah\startfile.bat
命令被自动执行。让你的批处理不输出任何东西。
答案2
如果要%f
在批处理文件中使用,则需要使用另一个来转义它%
:
for /f %%f in ('echo g ^| findstr "g"') do echo %%f
将其放入批处理文件中,您就会得到您想要的结果。
答案3
只是想稍微扩展一下 Vlastimil 的回答......
当。。。的时候FOR
命令执行"echo g"
并将输出传输至findstr
,为了必须首先启动一个新的命令处理器,这会导致\blah\startfile.bat
被执行。
\blah\启动文件.bat输出包含以下内容的行sss ttt
. 该行由为了并且是不是已传递给查找字符串。
根据帮助为了:
处理包括...,将其分解为单独的文本行,然后将每行解析为零个或多个标记。然后调用 for 循环的主体,并将变量值设置为找到的标记字符串。默认情况下,/F 传递每行中第一个空格分隔的标记...
默认分隔符为了是:“,;”(空格逗号和分号)。
第一行为了进程包含字符串:sss ttt。该字符串包含一个" "
(空格),这是默认的分隔符为了,它解析该行并分配第一个标记字符串:“嘶嘶”到“%F”。 所以“回显 %f”输出仅包含以下内容的行:“嘶嘶”。这是您看到的第一行打印内容。“ttt”被丢弃,因为“对于...回显%f”命令没有指定包含除第一个标记以外的任何内容。
如果为了命令写得不同,你会看到整行“嘶嘶嘶嘶”回响。
以下是 3 种方法为了可以编写命令来执行此操作。
第一种方式,使用"delims="
选项,设置分隔符为了为“空”,所以为了将整行作为 1 个标记返回。标记仍被解析,并且所有分隔符 (“,;”) 被删除,然后所有标记再次组合,每个标记之间有一个空格。此组合值在变量中返回“%F”
C:\>for /f "delims=" %f in ('echo sss ttt') do echo %f
C:\>echo sss ttt
sss ttt
C:\>for /f "delims=" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo %f
C:\>echo mm nn oo ss tt
mm nn oo ss tt
接下来的方法,使用"tokens=*"
选项,告诉为了将找到的所有标记放入指定变量的值中(“%F”)。仍旧解析标记,删除所有分隔符,然后重新组合所有标记,每个标记之间留有空格。
C:\>for /f "tokens=*" %f in ('echo sss ttt') do echo %f
C:\>echo sss ttt
sss ttt
C:\>for /f "tokens=*" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo %f
C:\Users\1-kevin>echo mm nn oo ss tt
mm nn oo ss tt
第三种方式,使用"tokens=1,*"
选项,告诉为了将找到的第一个 (1) 个标记放入指定变量的值中 (“%F”)。然后,解析剩余的标记,删除所有分隔符,然后将所有剩余的标记再次组合,每个标记之间有一个空格,并将此组合值返回到以指定变量名后面的字母命名的变量中(因此在本例中为变量“%G”)。
C:\>for /f "tokens=1,*" %f in ('echo sss ttt') do echo %f %g
C:\>echo sss ttt
sss ttt
C:\>for /f "tokens=1,*" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo "%f" "%g"
C:\>echo "mm" "nn oo ss tt"
"mm" "nn oo ss tt"
请注意,以下操作不起作用,因为没有为指定变量之外的变量定义“tokens=”“%F”:
C:\>for /f %f in ('echo sss ttt') do echo %f %g
C:\>echo sss %g
sss %g
因此,在您的示例中,如果您添加了"delims="
选项,你会看到:
C:\>for /f "delims=" %f in ('echo g ^| findstr "g"') do echo %f
C:\>echo sss ttt
sss ttt
C:\>echo g
g
C:\>