此 FOR 命令的输出有问题

此 FOR 命令的输出有问题

我刚刚意识到我在启动时在这个注册表项处执行了一个 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:\>

相关内容