簡體   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