电源外壳

电源外壳

我制作了一个小批处理文件,用于显示连接到 PC 的 USB 记忆棒和 SD 卡的大小、名称和 ID,以供测试。我尝试使用:~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%!

答案1

我将发布一个 PowerShell 的快速替代方案,以便进行比较,也因为谷歌搜索产生的大多是过时的弃用解决方案,也许更多的人会发现它有用:

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- 选择要在输出中显示的体积的这两个属性
  • @{ label="Size"; expression={ $_.Size -replace ".{9}$" } }- ... 第三个自定义表达式标记为,Size即删除最后 9 个字符的属性,在 a 中定义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

答案2

为什么不get一次一个item地、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.删除每个预先存在的 if/不存在的变量/值,这与下面的类似,但在一行/循环中:

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和第二%%ifor循环一起做的事情最好以以下方式形象化:
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. 现在我要删除变量/值_sSize排序大小!_Size!) 如果不存在/定义,则循环使用( 7725907968 7794573312) 中已定义并用空格分隔的值(sizeDrive1 SizeDrive2)如果未定义,则直接_sSize使用循环的初始值进行定义;如果已定义,则与当前值连接,但在定义时已经计算了字符串的最后 9 个字符:%%i%%icall set _sSize=!_sSize:~-9!


电源外壳

A展示与您的尝试类似的替代方法看起来像这样:

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"

CMD /commands /syntaxes /help

PS1 -commands -syntaxes -help


观察:建议操作员使用 powershell摧毁666受到欢迎,但当前的建议不能以接近/类似于您的尝试的方式重现输出,因此除了代码之外,您还有一种新的选择来编写输出:

PS G:\> Get-Volume | ? { $_.DriveType -eq "Removable" } | Select DriveLetter, FileSystemLabel, @{ label="Size"; expression={ $_.Size -replace ".{9}$" } }
DriveLetter FileSystemLabel Size
----------- --------------- ----
          G USBDRV          7   
          F SDCARDX         7   
$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
Disque USB Nom disque Taille dsk
---------- ---------- ----------
         G USBDRV     7         
         F SDCARDX    7         

观察:因此,由于环境已经能够接受 PowerShell,我将向您展示如何在同时建议使用与您的尝试类似的代码并获得更忠实于您在问题中发布的内容的输出,仅此而已。我明白现在您有多个选项可以尝试,我给了你一个,而Destroy666操作员给了你2个代码/选项。


相关内容