как отобразить размер периферийных устройств USB/SD в моей партии?
Я создал небольшой пакетный файл для отображения размера, имени и идентификатора USB-накопителей и SD-карт, подключенных к ПК, в целях тестирования. Я пытался использовать
:~0,-9%
чтобы сократить размер, отображаемый в байтах, это хорошо работает вне цикла для последнего элемента, но я не могу включить это выражение внутри цикла, если используется несколько периферийных устройств. Может кто-нибудь помочь и объяснить? Обратите внимание, что я новичок в пакетном программировании.
@echo off
setlocal enabledelayedexpansion
:chkUSB
set $List=
set $nom=
set $size=
for /f "skip=2 tokens=2-4 delims=," %%a in ('wmic logicaldisk where drivetype^=2 get deviceid^,Size^,VolumeName^ /format:csv^') do (
set "$List=!$List! %%a" & set "$size=!$size! %%b" & set "$nom=!$nom! %%c"
)
::Displaying USB/SD drives
rem set $size=!$size:~0,-9!
echo.
echo Disque USB : !$List!
echo nom disque : !$nom%!
echo taille dsk : !$size%!
2 ответа
Я опубликую быструю альтернативу PowerShell для сравнения, а также, поскольку поиск в Google дал в основном устаревшие устаревшие решения, возможно, больше людей найдут это полезным:
Get-Volume | ? { $_.DriveType -eq "Removable" } | Select DriveLetter, FileSystemLabel, @{ label="Size"; expression={ $_.Size -replace ".{9}$" } }
Пошаговое объяснение:
-
Get-Volume
- получает все доступные тома -
|
- каналы, которые передают последние результаты следующим функциям -
? { $_.DriveType -eq "Removable" }
- проверяет, еслиDriveType
свойство объемов равноRemovable
.?
это сокращение отWhere-Object
функция фильтрации. -
Select DriveLetter, FileSystemLabel
- выбирает эти 2 свойства томов для отображения на выходе -
@{ label="Size"; expression={ $_.Size -replace ".{9}$" } }
- ... и третье пользовательское выражение, помеченное какSize
это свойство с удаленными последними 9 символами, определенное вHashTable
. Можно также использовать, например$_.Size / 1GB
просто отобразить в определенной единице измерения.
С вашими собственными метками и использованием переменных:
$letter = @{ label="Disque USB"; expression={ $_.DriveLetter } }
$name = @{ label="Nom disque"; expression={ $_.FileSystemLabel } }
$size = @{ label="Taille dsk"; expression={ $_.Size -replace ".{9}$" } }
Get-Volume | ? { $_.DriveType -eq "Removable" } | Select $letter, $name, $size
Почему нетget
по одному, определить одинitem
за раз добавляйте по одномуvalue
кvariable
вовремя?
@echo off && setlocal enabledelayedexpansion
set "_get=DeviceID,VolumeName,Size"
for %%i in =;(!_get!)do set _%%~i=1<nul
for %%G in =;(!_get!)do for /f ^usebackq^tokens^=^4^delims^=^<^> %%i in =;(`
wmic logicaldisk where drivetype^=2 get %%~G /format:xml ^| find "VALUE"`
)do if not defined _%%G =;(set "_%%~G=%%~i")else set "_%%~G=!_%%~G! %%~i"
set "_sSize=" & for %%i in (!_Size!)do if not defined _sSize =;(
call set "_sSize=%%~i" && call set "_sSize=!_sSize:~0,-9!"
);= else =;(
call set "_sSize=!_sSize! %%~i" && call set "_sSize=!_sSize:~0,-9!"
);=
rem./::Displaying USB/SD drives & echo/
echo/Disque USB: !_DeviceID!
echo/nom disque: !_VolumeName!
echo/taille dsk: !_sSize!
endlocal & goto :eof
1. Определите элементы, которые будут использоваться для получения значений в цикле.wmic
команду, а также использовать их для имен переменных и соответствующей конкатенации:
set "_get=DeviceID,VolumeName,Size"
2. Удалите все ранее существовавшие/несуществующие переменные/значения, которые аналогичны вашим ниже, но в одной строке/цикле:
set $List=
set $nom=
set $size=
for %%i in =;(!_get!)do set _%%~i=1<nul
:: or...
for %%i in =;(DeviceID,VolumeName,Size)do set _%%~i=1<nul
3. Получите в начальном цикле имя элемента и используйте его для определения переменной, если она не определена, если она определена, используйте переменную цикла._%%G
для объединения с новым значением (!_%%G! + %%i
), полученное от каждого водителя/объекта.
for %%G in =;(!_get!)do for /f ^usebackq^tokens^=^4^delims^=^<^>^ %%i in =;(`
wmic logicaldisk where drivetype^=2 get %%~G /format:xml ^| find "VALUE"`
)do if not defined _%%G =;(set "_%%G=%%~i")else set "_%%~G=!_%%~G! %%~i"
- Обс.: Что 1-го
%%G
и 2-йвfor
циклы выполняются вместе, лучше всего визуализировать следующим образом:
for %%G in =;(DeviceID)do for /f ^usebackq^tokens^=^4^delims^=^<^> %%i in =;(`
wmic logicaldisk where drivetype^=2 get DeviceID /format:xml ^| find "VALUE"`
)do if not defined _DeviceID =;(set "_DeviceID=%%~i")else set "_DeviceID=!_DeviceID! %%~i"
for %%G in =;(VolumeName)do for /f ^usebackq^tokens^=^4^delims^=^<^> %%i in =;(`
wmic logicaldisk where drivetype^=2 get VolumeName /format:xml ^| find "VALUE"`
)do if not defined _VolumeName =;(set "_VolumeName=%%~i")else set "_VolumeName=!_VolumeName! %%~i"
for %%G in =;(Size)do for /f ^usebackq^tokens^=^4^delims^=^<^> %%i in =;(`
wmic logicaldisk where drivetype^=2 get Size /format:xml ^| find "VALUE"`
)do if not defined _Size =;(set "_Size=%%~i")else set "_Size=!_Size! %%~i"
4. Теперь я удаляю переменную/значение ( размер сортировки ), если/не существует/определено, и зацикливаюсь на использовании значений, используя значения, уже определенные в!_Size!
(7725907968 7794573312
) и разделены пробелом
(sizeDrive1 SizeDrive2)
и прямо определено_sSize
с начальным значением цикла, если оно не определено, и объединением с текущим значением%%i
если он уже определен, но уже считает строку, удаляя последние 9 символов при ее определении вcall set _sSize=!_sSize:~-9!
:
PowerShell
Альтернатива , демонстрирующая аналогичную вашу попытку, будет выглядеть примерно так:
Rv -Na dev,nam,size 2>$null
Get-CimInstance win32_logicaldisk -f "Drivetype=2" | Select 'DeviceID','VolumeName','Size' | ? {
$dev=$dev+' '+$_.DeviceID; $nam=$nam+' '+$_.VolumeName; $size=$size+' '+[math]::round($_.Size/1GB) }
Write "`nDisque USB :$dev`nnom disque :$nam`ntaille dsk :$size"
- Выход:
Disque USB : F: G:
nom disque : SDCARDX USBDRV
taille dsk : 7 7
- Тот же код, но без использования псевдонимов, это будет:
# Remove variables from previous runs
Remove-Variable -Name dev,nam,size
# PS1 "wmic" command in loop to get and cancatenate values for
Get-CimInstance win32_logicaldisk -f "Drivetype=2" | Select-Object 'DeviceID','VolumeName','Size' | Foreach-Object {
# Define and loop concatenate values to your variables
$dev=$dev+' '+$_.DeviceID; $nam=$nam+' '+$_.VolumeName; $size=$size+' '+[math]::round($_.Size/1GB) }
# Print on screen your sorted values line by line (`n == new line)
Write-Output "`nDisque USB :$dev`nnom disque :$nam`ntaille dsk :$size"
Набл.: Предложение использовать PowerShell с помощью оператора приветствуется, но текущие предложения не воспроизводят выходные данные так же, как ваша попытка, поэтому в дополнение к коду у вас есть новая альтернатива для составления вывод тоже:
- Текущий код предложения №1
PS G:\> Get-Volume | ? { $_.DriveType -eq "Removable" } | Select DriveLetter, FileSystemLabel, @{ label="Size"; expression={ $_.Size -replace ".{9}$" } }
- Текущий вывод предложения № 1:
DriveLetter FileSystemLabel Size
----------- --------------- ----
G USBDRV 7
F SDCARDX 7
- Текущий код предложения №2
$letter = @{ label="Disque USB"; expression={ $_.DriveLetter } }
$name = @{ label="Nom disque"; expression={ $_.FileSystemLabel } }
$size = @{ label="Taille dsk"; expression={ $_.Size -replace ".{9}$" } }
Get-Volume | ? { $_.DriveType -eq "Removable" } | Select $letter, $name, $size
- Текущее предложение Destroy666 № 2. Вывод:
Disque USB Nom disque Taille dsk
---------- ---------- ----------
G USBDRV 7
F SDCARDX 7
Набл.: Итак, поскольку среда стала восприимчивой к PowerShell, я показываю вам, как можно использовать wmic в powershellpowershellPowerShell , и в то же время предлагаю использовать код, аналогичный вашим попыткам, и получать выходные данные, более соответствующие тому, что вы опубликовали. в вопросе это все. Я понимаю, что теперь у вас есть несколько вариантов попробовать , я дал вам один, а оператор Destroy666 дал вам 2 кода/параметра.