如何在/ F的循环内设置变量

时间:2012-12-10 16:39:26

标签: batch-file cmd

我制作了这段代码

dir /B /S %RepToRead% > %FileName%

for /F "tokens=*" %%a in ('type %FileName%') do (
    set z=%%a
    echo %z%
    echo %%a
)

echo %%a工作正常但echo %z%返回“已禁用回声”。

我需要设置%z%,因为我想将变量分割为%z:~7%

有什么想法吗?

9 个答案:

答案 0 :(得分:54)

在for循环和括号范围内设置和使用变量有两种方法。

  1. setlocal enabledelayedexpansion请参阅setlocal /?寻求帮助。这仅适用于XP / 2000或更新版本的Windows。 然后在循环中使用!variable!代替%variable% ...

  2. 使用批量转到标签:Label创建批处理功能。

    示例:

    for /F "tokens=*" %%a in ('type %FileName%') do call :Foo %%a
    goto End
    
    :Foo
    set z=%1
    echo %z%
    echo %1
    goto :eof
    
    :End
    

    批处理功能是非常有用的机制。

答案 1 :(得分:32)

你可能想要SETLOCAL ENABLEDELAYEDEXPANSION。有关详细信息,请参阅https://devblogs.microsoft.com/oldnewthing/20060823-00/?p=29993

基本上:在%variables%读取命令后立即展开正常cmd.exe。在你的情况下,“命令”是整个

for /F "tokens=*" %%a in ('type %FileName%') do (
    set z=%%a
    echo %z%
    echo %%a
)

环。此时z尚无值,因此echo %z%变为echo。然后执行循环并设置z,但不再使用它的值。

SETLOCAL ENABLEDELAYEDEXPANSION启用了其他语法!variable!。这也扩展了变量,但它只在每个(子)命令执行之前才这样做。

SETLOCAL ENABLEDELAYEDEXPANSION
for /F "tokens=*" %%a in ('type %FileName%') do (
    set z=%%a
    echo !z!
    echo %%a
)

每次z运行时,这会为您提供echo的当前值。

答案 2 :(得分:8)

我坚持了好几个小时。 这是我注册命令行变量的循环。 示例:Register.bat / param1:value1 / param2:value2

是什么,循环所有命令行参数, 并将该变量设置为值的正确名称。

之后,你可以使用 设定值=!param1! set value2 =!param2!

无论序列如何给出。 (所谓的命名参数)。 请注意!<>!而不是%<>%。

SETLOCAL ENABLEDELAYEDEXPANSION

FOR %%P IN (%*) DO (
    call :processParam %%P
)

goto:End

:processParam [%1 - param]

    @echo "processparam : %1"
    FOR /F "tokens=1,2 delims=:" %%G IN ("%1") DO (
        @echo a,b %%G %%H
        set nameWithSlash=%%G
        set name=!nameWithSlash:~1!
        @echo n=!name!
        set value=%%H
        set !name!=!value!
    )
    goto :eof

:End    

答案 3 :(得分:1)

使用%var%、! var!和%%的批处理代码的简单示例。

在此示例代码中,这里的重点是我们要使用内置变量TIME(使用时间,因为它总是自动更改)来捕获开始时间:

代码:

@echo off
setlocal enabledelayedexpansion
SET "SERVICES_LIST=MMS ARSM MMS2"
SET START=%TIME%
SET "LAST_SERVICE="

for %%A in (%SERVICES_LIST%) do (
    SET START=!TIME!
    CALL :SOME_FUNCTION %%A
    SET "LAST_SERVICE=%%A"
    ping -n 5 127.0.0.1 > NUL
    SET OTHER=!START!
    if !OTHER! EQU !START! (
    echo !OTHER! is equal to !START! as expected
    ) ELSE (
    echo NOTHING
    )
)
ECHO Last service run was %LAST_SERVICE%

:: Function declared like this
:SOME_FUNCTION
echo Running: %1
EXIT /B 0

对代码的评论:

  • 使用enabledelayedexpansion
  • 前三行SET是典型的 使用SET命令时,大部分时间都使用此命令。
  • 下一行是for循环,必须使用%% A进行迭代,如果其中包含循环,则必须使用%% B 等等。您不能使用长变量名。
  • 要访问已更改的变量(例如时间变量),必须使用!!!或设置! (已启用enableddelayexpansion)。
  • 在for循环中循环时,每个迭代都作为%% A变量进行访问。
  • for循环中的代码指出了设置变量的各种方法。查看“ SET OTHER =!START!”,如果您要更改为SET OTHER =%START%,您将明白原因!是必需的。 (提示:您将看到“无”)输出。
  • 简而言之!更有可能需要在循环内使用,通常为%var%,%%始终为for循环。

进一步阅读

使用以下链接来详细确定原因:

答案 4 :(得分:0)

set list = a1-2019 a3-2018 a4-2017
setlocal enabledelayedexpansion
set backup=
set bb1=

for /d %%d in (%list%) do (
   set td=%%d
   set x=!td!
   set y=!td!
   set y=!y:~-4!
   if !y! gtr !bb1! (
     set bb1=!y!
     set backup=!x!
   )
)

rem: backup will be 2019
echo %backup% 

答案 5 :(得分:0)

为了扩展答案,我来这里是为了更好地理解,所以我写了这篇可以解释的书,也为我提供了帮助。

其中有setlocal DisableDelayedExpansion,因此您可以根据需要在setlocal EnableDelayedExpansion和它之间进行本地设置。

@echo off
title %~nx0
for /f "tokens=*" %%A in ("Some Thing") do (
  setlocal EnableDelayedExpansion
  set z=%%A
  echo !z!        Echoing the assigned variable in setlocal scope.
  echo %%A        Echoing the variable in local scope.
  setlocal DisableDelayedExpansion
  echo !z!        &rem !z!           Neither of these now work, which makes sense.
  echo %z%        &rem ECHO is off.  Neither of these now work, which makes sense.
  echo %%A        Echoing the variable in its local scope, will always work.
  )

答案 6 :(得分:-1)

试试这个:

setlocal EnableDelayedExpansion

...

for /F "tokens=*" %%a in ('type %FileName%') do (
    set z=%%a
    echo !z!
    echo %%a
)

答案 7 :(得分:-2)

以下内容应该有效:

setlocal EnableDelayedExpansion
for /F "tokens=*" %%a in ('type %FileName%') do (
    set "z=%%a"
    echo %z%
    echo %%a
)

答案 8 :(得分:-3)

我知道这不是要问的问题,但是当尝试在“循环”中设置变量时,我从该方法中受益。使用数组。替代实施选项。

const tsImportPluginFactory = require('ts-import-plugin')
const { getLoader } = require("react-app-rewired");
const rewireLess = require('react-app-rewire-less');

module.exports = function override(config, env) {
  const tsLoader = getLoader(
    config.module.rules,
    rule =>
      rule.loader &&
      typeof rule.loader === 'string' &&
      rule.loader.includes('ts-loader')
  );

  tsLoader.options = {
    getCustomTransformers: () => ({
      before: [ tsImportPluginFactory({
        libraryName: 'antd',
        libraryDirectory: 'es',
         style: true,
      }) ]
    })
  };

// rewireLess.withLoaderOptions({javascriptEnabled: true})(config, env);
   config = rewireLess.withLoaderOptions({
     modifyVars: { **"@primary-color": "#1DA57A"** }, javascriptEnabled: true
   })(config, env);

  return config;
}