【问题标题】:Issues with spaces in FOR loop variable - batch scriptFOR 循环变量中的空格问题 - 批处理脚本
【发布时间】:2016-05-17 17:10:04
【问题描述】:

我正在编写一个批处理脚本,它将使用 WMIC 命令获取 Windows 机器上所有组的列表,使用 net localgroup <groupname> 获取组信息,然后将信息写入输出文件。这是我所拥有的:

for /f "skip=1" %%a in ('"wmic group get name"') do net localgroup %%a  >> "%OUTPUTFILEPATH%" 2> nul && echo.  >> "%OUTPUTFILEPATH%" && echo ^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=  >> "%OUTPUTFILEPATH%" && echo. >> "%OUTPUTFILEPATH%"

我遇到的问题似乎是在 do net localgroup %%a 中获取 %%a 变量的引号,因为它可以很好地输出像管理员这样的组的信息,但是当它到达像远程桌面用户这样的组名时,它会失败返回组的信息。

换句话说,这似乎是在 FOR 循环中发生的事情:

net localgroup Administrators
net localgroup Remote Desktop Administrators

第一次操作成功。第二个不是。显然,需要在 Remote Desktop Administrators 周围加上引号才能将其视为单个参数,但我不太清楚如何为我的 %%a FOR 循环变量实现这一点。

我尝试在"%%a"'%%a' 周围加上引号。这没有帮助。

任何意见将不胜感激。

【问题讨论】:

    标签: windows batch-file command-line cmd scripting


    【解决方案1】:

    试试:

    for /f "tokens=*" %%a in ('"wmic group get name"') do ....
    

    【讨论】:

    • 感谢您的意见!这似乎没有成功。当使用 'for /f "tokens=*" %%a in ('"wmic group get name"') do net localgroup %%a' 而不是 for /f "skip=1" %%a in ('"wmic group get name"') do net localgroup %%a 我仍然一遍又一遍地收到很多 The syntax of this command is: NET LOCALGROUP [groupname [/COMMENT:"text"]] [/DOMAIN] groupname {/ADD [/COMMENT:"text"] | /DELETE} [/DOMAIN] groupname name [...] {/ADD | /DELETE} [/DOMAIN]再次在 STDERR 中,现在它甚至不再记录单空格组名称
    【解决方案2】:

    您需要按照Carlos Gutiérrez 的建议使用tokens=*,或者在FOR 上使用更好的delims=,以避免根据空格和制表符将行拆分为标记。

    当任何组名包含 1 个或多个空格时,当然还需要将组名用双引号括起来。

    但这里的主要问题是wmic 以 UTF-16 Little Endian 编码的 Unicode 输出信息,命令 FOR 无法直接正确解析。此问题的解决方法是将wmic 的输出重定向到临时文本文件并使用命令type 以ASCII/ANSI/OEM 格式获取内容,即每个字符一个字节。有关详细信息,请参阅How to correct variable overwriting misbehavior when parsing output 上的答案。

    但这里还有一个问题,因为wmic 输出的组名带有尾随空格。在将组名作为参数传递给用双引号括起来的控制台应用程序 net 之前,必须额外删除这些尾随空格。

    @echo off
    setlocal EnableDelayedExpansion
    set "OutputFile=%USERPROFILE%\Desktop\LocalGroupInfo.txt"
    del "%OutputFile%" 2>nul
    %SystemRoot%\System32\wbem\wmic.exe group get name >"%Temp%\%~n0.tmp"
    for /f "skip=1 delims=" %%a in ('type "%Temp%\%~n0.tmp"') do (
        set "GroupName=%%a"
        call :RemoveTrailingSpaces
        %SystemRoot%\System32\net.exe localgroup "!GroupName!" >>"%OutputFile%" 2>nul
        if not errorlevel 1 (
            echo.>>"%OutputFile%"
            echo ==========================================>>"%OutputFile%"
            echo.>>"%OutputFile%"
        )
    )
    del "%Temp%\%~n0.tmp"
    endlocal
    
    :RemoveTrailingSpaces
    if not "%GroupName:~-1%" == " " exit /B
    set "GroupName=%GroupName:~0,-1%"
    goto RemoveTrailingSpaces
    

    要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

    • call /?
    • del /?
    • echo /?
    • endlocal /?
    • exit /?
    • for /?
    • goto /?
    • if /?
    • net localgroup /?
    • set /?
    • setlocal /?
    • type /?
    • wmic group get /?

    【讨论】:

      【解决方案3】:

      快速移动

      @ECHO OFF
      SETLOCAL ENABLEDELAYEDEXPANSION 
      SET "OUTPUTFILEPATH=u:\ofp.txt"
      DEL  /F /Q "%outputfilepath%"
      for /f "skip=1delims=" %%a in ('wmic group get name') do (
       SET "group=%%a"
       CALL :loptrail
       IF DEFINED group (
        net localgroup "!group!"  >> "%OUTPUTFILEPATH%" 2> NUL
        echo.>> "%OUTPUTFILEPATH%"
        echo ==========================================>> "%OUTPUTFILEPATH%"
        echo.>> "%OUTPUTFILEPATH%"
       )
      )
      
      GOTO :EOF
      
      :loptrail
      SET "group=%group:~0,-1%"
      IF "%group:~-1%"==" " GOTO loptrail
      GOTO :eof
      

      问题是 wmic 输出是 unicode 并且 %%a 需要 delims= 否则它返回第一个 [implicit-space] 分隔的标记。

      不幸的是,这意味着%%a 包含尾随空格,net 似乎不赞成。

      由于批处理不允许对元变量进行子字符串化,因此您需要将其放入公共环境变量并调用enabledelayedexpansion

      group 中的值似乎被一个额外的NULL 终止,因此:loptrail 例程首先任意删除最后一个字符,然后是任何剩余的尾随空格。

      wmic 输出的最后一行将生成一个孤零零的空 group,因此仅当 group 非空时,net 处理才会继续。

      【讨论】:

      • 做到了!感谢您的帮助和详尽的解释!
      猜你喜欢
      • 2022-01-22
      • 2012-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2017-02-03
      • 1970-01-01
      • 2013-08-08
      相关资源
      最近更新 更多