[英]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.