8

コンピュータに搭載されているすべてのディスク ドライブのリストを (とりわけ) 取得するバッチ スクリプトを作成しようとしています。基本的なコードは次のようになります。

REM Build the list of disk drives to monitor
SETLOCAL enabledelayedexpansion
FOR /f "skip=1 tokens=1 delims=:" %%a in ('"WMIC logicaldisk WHERE drivetype=3 GET deviceid"') do (
    SET "DISK_DATABASES=!DISK_DATABASES!%%a|"
    SET "DRIVES_TO_MONITOR=!DRIVES_TO_MONITOR!%%a:\\|"
)

後で使用するために、形式がわずかに異なる 2 つのリストを作成していることは明らかです。ただし、これを実行すると、得られる出力は次のようになります。

C|D|E||
C:\\|D:\\|E:\\|:\\|

今、私はどちらの場合も末尾のパイプを期待しており、それを管理できますが、そこに余分な空白のエントリがある理由が本当に混乱しています. コマンドを手動で実行するwmicと、実際には出力の最後に空白行があることがわかりますが、私の理解では、/f空白行を無視することになっていました。

オンECHOにすると、最後の行が改行/改行などとして入っているように見えます。私が期待していることを行う方法はありますか?何か不足していますか?この最後の行を除外する条件をループに書き込もうとしましたifが、それは... ファンキーで、うまくいきませんでした。あらゆる/すべての助けに感謝します。

4

7 に答える 7

5

C|D|E||この場合、最後の反復は空のアイテムを生成せず、 with のみの出力を取得しますが 、echo %DISK_DATABASES%??を出力します。
echo !DISK_DATABASES!||D|E|

これは、最後の要素が 1 <CR>文字であるためです。
また、<CR>文字はパーセント展開後に直接削除されますが、遅延展開では削除されません。

パーセント展開を使用してそれらを削除することで、これを回避できます

setlocal EnableDelayedExpansion
FOR /f "skip=1 tokens=1 delims=:" %%a in ('"WMIC logicaldisk WHERE drivetype=3 GET deviceid"') do (
  set "item=%%a"
  call :removeCR

  if not "!item!"=="" (
    SET "DISK_DATABASES=!DISK_DATABASES!!item!|"
    SET "DRIVES_TO_MONITOR=!DRIVES_TO_MONITOR!!item!:\\|"
  )
)
goto :eof
:removeCR

:removeCR
set "Item=%Item%"
exit /b
于 2011-11-05T07:54:47.283 に答える
4

http://ss64.com/nt/for_f.htmlによると

新しいコマンドやユーティリティ (WMIC など) の多くはテキスト ファイルを Unicode 形式で出力しますが、これらは ASCII を想定する FOR コマンドでは読み取ることができません。ファイル形式を変換するには、TYPE コマンドを使用します。

したがって、WMIC と FOR は相性が悪いようです。

于 2011-11-04T23:55:33.650 に答える
1

追加^| findstr .すると、空白行だけが取得されます

    REM 監視するディスク ドライブのリストを作成します
    SETLOCAL が有効な遅延拡張
    FOR /f "skip=1 tokens=1 delims=:" %%a in (
    '"WMIC logicaldisk WHERE drivetype=3 GET deviceid" ^| findstr .') する (
        SET "DISK_DATABASES=!DISK_DATABASES!%%a|"
        SET "DRIVES_TO_MONITOR=!DRIVES_TO_MONITOR!%%a:\|"
    )
    

于 2017-01-11T17:37:13.087 に答える
0

これに対処するための私の標準的なイディオムは、WMIC からの出力を一時ファイルに書き込み、次に TYPE (UTF16 を ASCII に縮小) を使用して、次のように FOR にフィードすることです。

:: Standard environment setup
setlocal enabledelayedexpansion
:: Every variable whose name starts with "tf" will identify a temporary
:: file - remove any such variables inherited from the parent environment
for /f %%V in ('set tf') do set %%V=
:: Create some temporary filenames. Prefix all of them with this script's
:: own name to avoid clashes with those owned by other scripts.
for /l %%I in (1,1,4) set tf%%I="%temp%\%~n0-temp%%I.txt"

:: Use temp file to work around coding mismatch between WMIC out and FOR in
wmic product where "name like 'Microsoft Office %% 2010'" get packagecache >!tf1!
for /f "skip=1" %%P in ('type !tf1!') do if exist "%%~P" msiexec /x "%%~P" /passive /norestart

:: Before quitting script, clean up temporary files
for /f %%V in ('set tf') do if exist "%%~V" del /f /q "%%~V"
endlocal
于 2013-05-19T08:55:00.600 に答える