繁体   English   中英

FOR循环变量中的空格问题-批处理脚本

[英]Issues with spaces in FOR loop variable - batch script

我正在编写一个批处理脚本,该脚本将使用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变量周围的引号有关,因为它可以很好地输出诸如Administrators之类的组的信息,但是当它获得诸如Remote Desktop Users之类的组名时,它将失败返回该组的信息。

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

net localgroup Administrators
net localgroup Remote Desktop Administrators

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

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

任何投入将不胜感激。

你需要为使用tokens=*所建议古铁雷斯甚至更好delims= ,以避免分裂行成基于空格和制表符标记。

当然,如果任何组名包含1个或多个空格,则还必须将组名用双引号引起来。

但是这里的主要问题是wmic以UTF-16 Little Endian编码以Unicode输出信息,而FOR命令无法直接正确解析。 解决此问题的方法是将wmic输出重定向到一个临时文本文件,并使用命令type获取ASCII / ANSI / OEM中的内容,即每个字符一个字节。 有关详细信息,请参见解析输出时如何更正变量覆盖行为的答案。

但是这里还有另一个问题,因为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 /?

快速眼动

@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=否则它将返回第一个[隐式空格]分隔的标记。

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

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

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

wmic输出的最后一行将生成一个孤立的空group因此仅当group为非空时才进行net处理。

尝试:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM