Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Batch file “怎么做?”;至于;在cmd批处理文件中工作?_Batch File_Iteration_Cmd - Fatal编程技术网

Batch file “怎么做?”;至于;在cmd批处理文件中工作?

Batch file “怎么做?”;至于;在cmd批处理文件中工作?,batch-file,iteration,cmd,Batch File,Iteration,Cmd,我已经用几十种语言编程20年了,但无论我怎么努力,我都无法理解“for”在windows cmd shell批处理文件中是如何工作的。我读 和其他几篇文章在互联网上,但仍然混淆,无法完成任何事情 有谁能给我一个关于“FOR”一般如何工作的简明解释吗 对于一个更具体的问题,我如何遍历%path%变量中的每个路径? 我试过了 rem showpathenv.bat for /f "delims=;" %%g in ("%PATH%") do echo %%g 这将只显示第一条路径,而不是所有路

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

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

有谁能给我一个关于“FOR”一般如何工作的简明解释吗

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

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

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

for/f
迭代每行输入,因此在您的程序中只输出第一条路径


您的程序将%PATH%视为一行输入,并通过
清除
,将第一个结果放入%%g,然后输出%%g(第一个清除路径)。

您的想法是正确的,但是
for/f
设计用于多行文件或命令,而不是单个字符串

在其最简单的形式中,
for
类似于Perl的
for
,或其他任何语言的
foreach
。您向它传递一个令牌列表,它对它们进行迭代,每次调用相同的命令

for %a in (hello world) do @echo %a
扩展只提供了自动构建令牌列表的方法。您当前的代码没有任何结果的原因是“
”是默认的行尾(注释)符号。但是,即使您更改了它,您也必须使用
%%g、%%h、%%i、
来访问各个令牌,这将严重限制批处理文件

最接近你所要求的是:

set TabbedPath=%PATH:;= %
for %%g in (%TabbedPath%) do echo %%g
但对于包含分号的带引号的路径,这将失败

根据我的经验,
for/l
for/r
有助于扩展现有命令,但在其他方面,
for
非常有限。通过延迟变量扩展(
cmd/v:on
),您可以使它稍微更强大(并且更容易混淆),但它实际上只适用于文件名列表


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

for
实际上是在数据集中的“行”上迭代。在本例中,有一行包含路径。
“delims=;”
只是告诉它用分号分开。如果将正文更改为
echo%%g、%%h、%%i、%%j、%%k
,您将看到它将输入视为一行,并将其拆分为多个标记。

以下是一个很好的指南:

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


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

所有答案都不起作用。我自己已经找到了解决方案。 这有点老套,但它解决了我的问题:

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的想法很好,但可能忘记了某些路径中有空格。将“;”替换为“”,会将所有路径切割为带引号的字符串

set _path="%PATH:;=" "%"
for %%p in (%_path%) do if not "%%~p"=="" echo %%~p
在这里,你可以看到你的路径

cmd中的FOR命令有一个冗长的学习曲线,特别是因为变量在()语句中的反应……您可以分配任何变量,但不能在()语句中读取,除非您使用“setlocal ENABLEDELAYEDEXPANSION”语句,因此也使用带!!的变量,而不是%%的(!\u var!)

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

这对我来说很有用:

@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

您还必须使用
for
循环允许的
选项的
标记=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不同

为了保存带有空格的路径,请在all%x周围加上类似“%i”的引号。我在这里没有这样做,因为我只是回显标记

你也可以这样做:

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是如何以相反的顺序处理的,以及它们现在是如何“表示”不同的标记的


因此,这肯定不是您要求的简明解释。但也许这些示例现在有助于更好地澄清…

我知道这是非常古老的…但为了好玩,我决定尝试一下:

@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
函数。

忍不住把它扔到那里,尽管这个线程很旧……通常在需要迭代每个fi时在路径中,您真正想要做的就是找到一个特定的文件…如果是这样,这个一行程序将吐出它在其中找到您的文件的第一个目录:

(例如:查找java.exe)


这对我有用,试试看

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

这对我有用,试试看

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

对于/f“tokens=*delims=;%g in('echo%PATH%”)do echo%g%

但是,请注意,如果第一个路径中有分号,则此操作将失败。在本例中,由for完成的标记化将无法处理引用。我不理解/?帮助并寻求更多解释或示例。可能是我对批处理文件的期望过高。感谢您的回答。我可能对WSH或PowerShell不感兴趣l、 因为我已经在做Python了。我根据你的指南提出了解决方案。请看我下面的回答你说“[…]