我已经用几十种语言编程了20年,但我永远无法理解“FOR”是怎样的。在Windows cmd shell批处理文件中工作,无论我怎么努力。我读了

http://www.amazon.com/Windows-Administration-Command-Line- VISTA / DP / 0470046163 / REF = sr_1_1即= UTF8&安培; S =书籍和安培; QID = 1241362727&安培; SR = 8-1

http://www.ss64.com/nt/for.html

和互联网上的其他几篇文章但仍然混淆,无法完成任何事情。

任何人都可以给我一个简明的解释,说明如何“FOR”一般工作吗?

对于更具体的问题,我如何遍历%PATH%变量中的每个路径? 我试过

rem showpathenv.bat
for /f "delims=;" %%g in ("%PATH%") do echo %%g

这只显示第一条路径,而不是所有路径。为什么?我做错了什么?

有帮助吗?

解决方案

所有答案都没有实际效果。我自己设法找到了解决方案。 这有点hackish,但它解决了我的问题:

echo off
setlocal enableextensions
setlocal enabledelayedexpansion
set MAX_TRIES=100
set P=%PATH%
for /L %%a in (1, 1, %MAX_TRIES%) do (
  for /F "delims=;" %%g in ("!P!") do (
    echo %%g
    set P=!P:%%g;=!
    if "!P!" == "%%g" goto :eof
  )
)
哦,哦!我讨厌批量文件编程!!

<强>更新

Mark的解决方案更简单,但它不适用于包含空格的路径。这是Mark解决方案的一个小修改版本

echo off
setlocal enabledelayedexpansion
set NonBlankPath=%PATH: =#%
set TabbedPath=%NonBlankPath:;= %
for %%g in (%TabbedPath%) do (
  set GG=%%g
  echo !GG:#= !
)

其他提示

Mark的想法很好,但也许忘记了一些路径中有空格。替换';'与'' &QUOT;”而是将所有路径切换为带引号的字符串。

set _path="%PATH:;=" "%"
for %%p in (%_path%) do if not "%%~p"=="" echo %%~p

所以在这里,你显示了你的路径。

cmd中的FOR命令有一个繁琐的学习曲线,特别是因为变量如何在()的语句中作出反应...你可以分配任何变量,但你不能在()中读回,除非你使用“setlocal ENABLEDELAYEDEXPANSION”语句,因此也使用变量!!而不是%%的(!_var!)

我目前只使用cmd编写脚本,为了工作,必须学习所有这些:)

你有正确的想法,但/ f 的旨在处理多行文件或命令,而不是单个字符串。

最简单的形式是 for 就像Perl的 for ,或者每个其他语言的 foreach 。你传递一个令牌列表,然后迭代它们,每次调用相同的命令。

for %a in (hello world) do @echo %a

扩展仅提供构建令牌列表的自动方式。您当前代码没有任何结果的原因是'; '是行(注释)符号的默认结尾。但即使你改变了,你也必须使用 %% g,%% h,%% i,... 来访问各个令牌,这将严重限制你的批处理文件。 / p>

你能得到的最接近的是:

set TabbedPath=%PATH:;= %
for %%g in (%TabbedPath%) do echo %%g

但对于包含分号的引用路径,这将失败。

根据我的经验,/ l 和/ r 适用于扩展现有命令,但 for 非常有限。你可以使用延迟变量扩展( cmd / v:on )使它更强大(并且令人困惑),但它实际上只对文件名列表有用。

如果您需要执行字符串操作,我建议使用WSH或PowerShell。如果您正在尝试为Windows编写 whereis ,请尝试 where /?

无法抗拒把它抛出那里,因为这个线程很老......通常当需要迭代遍历PATH中的每个文件时,你真正想做的就是找到一个特定的文件......如果在这种情况下,这个单行将吐出它找到你的文件的第一个目录:

(例如:寻找java.exe)

for %%x in (java.exe) do echo %%~dp$PATH:x

我知道这是超级老......但为了好玩,我决定尝试一下:

@Echo OFF
setlocal
set testpath=%path: =#%
FOR /F "tokens=* delims=;" %%P in ("%testpath%") do call :loop %%P
:loop
if '%1'=='' goto endloop
set testpath=%1
set testpath=%testpath:#= %
echo %testpath%
SHIFT
goto :loop
:endloop
pause
endlocal
exit

这不需要计数,直到完成为止。我对空格有同样的问题,但它通过整个变量。关键是循环标签和 SHIFT 功能。

/ f

迭代每行输入,因此在你的程序中只会输出第一个路径。

你的程序将%PATH%视为单行输入,并通过; 进行消除,将第一个结果放到%% g,然后输出%% g(第一个消除路径)。

FOR 基本上是在“行”上进行迭代。在数据集中。在这种情况下,有一行包含路径。 &quot; delims =;&quot; 只是告诉它在分号上分开。如果将主体更改为 echo %% g,%% h,%% i,%% j,%% k ,您将看到它将输入视为单行并将其分解多个令牌。

这对我有用:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
@REM insure path is terminated with a ;
set tpath=%path%;
echo.
:again
@REM This FOR statement grabs the first element in the path
FOR /F "delims=;" %%I IN ("%TPATH%") DO (
  echo    %%I 
  @REM remove the current element of the path
  set TPATH=!TPATH:%%I;=!
)
@REM loop back if there is more to do. 
IF DEFINED TPATH GOTO :again

ENDLOCAL

您还必须使用 tokens = 1,2,... 循环允许的选项的一部分。这可以做你想要的事情:

for /f "tokens=1,2,3,4,5,6,7,8,9,10,11,12 delims=;" %a in ("%PATH%") ^
do ( ^
     echo. %b ^
   & echo. %a ^
   & echo. %c ^
   & echo. %d ^
   & echo. %e ^
   & echo. %f ^
   & echo. %g ^
   & echo. %h ^
   & echo. %i ^
   & echo. %j ^
   & echo. %k ^
   & echo. ^
   & echo.   ...and now for some more... ^
   & echo. ^
   & echo. %a ^| %b ___ %c ... %d ^
   & dir "%e" ^
   & cd "%f" ^
   & dir /tw "%g" ^
   & echo. "%h  %i  %j  %k" ^
   & cacls "%f")

此示例仅处理前12个令牌(=来自%path%的目录)。它使用每个使用过的令牌的显式枚举。请注意,令牌名称区分大小写:%a与%A不同。

要保存包含空格的路径,请使用类似“%i”的引号将 所有 %x环绕。我没有在这里做,我只是回应了令牌。

你也可以做s.th.像这样:

for /f "tokens=1,3,5,7-26* delims=;" %a in ("%PATH%") ^
do ( ^
     echo. %c ^
   & echo. %b ^
   & echo. %a ^
   & echo. %d ^
   & echo. %e ^
   & echo. %f ^
   & echo. %g ^
   & echo. %h ^
   & echo. %i ^
   & echo. %j ^
   & echo. %k )

这个跳过令牌2,4,6并使用一个小快捷方式(“ 7-26 ”)来命名其余的。请注意,与第一个示例相比,此次如何以相反的顺序处理%c,%b,%a,以及它们现在的“意味着”不同的标记。

所以这肯定不是你要求的简明解释。但也许这些例子现在有助于澄清一点......

这是一个很好的指南:

FOR / F - 循环命令:针对一组文件。

FOR / F - 循环命令:针对另一个命令的结果。

FOR - 循环命令:所有选项文件,目录,列表。

[整个指南(Windows XP命令):

http://www.ss64.com/nt/index.html

编辑:抱歉,没有看到该链接已经在OP中,因为它在我看来是亚马逊链接的一部分。

它对我有用,试一试。

for /f "delims=;" %g in ('echo %PATH%') do echo %g%

它对我有用,试一试。

for / f&quot; tokens = * delims =;&quot; ('echo%PATH%')中的%g执行回显%g%

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top