标题: [其他] [分享]批处理用for /f从wmic的结果中正确取值 [打印本页]
作者: buyiyang 时间: 2023-4-7 15:38 标题: [分享]批处理用for /f从wmic的结果中正确取值
据我观察,如何用for /f从wmic的结果中正确取值的问题还是困扰了许多人,一开始我也被困扰过,比如执行以下命令来获取ExecutablePath:- for /f "delims=" %%i in ('wmic process where "Name='WMIC.exe'" get ExecutablePath') do echo %%i
复制代码
cmd窗口回显是这样的(加了个注意方便观察):- >for /F "delims=" %i in ('wmic process where "Name='WMIC.exe'" get ExecutablePath') do echo %i注意
-
- 注意 >echo ExecutablePath
- 注意utablePath
-
- 注意 >echo C:\windows\System32\Wbem\WMIC.exe
- 注意indows\System32\Wbem\WMIC.exe
-
- 注意 >echo
- 注意
复制代码
你会发现“注意”这两个字跑到前面去了,这是为什么呢?把wmic process where "Name='WMIC.exe'" get ExecutablePath的结果重定向到文件里,然后用编辑器打开:- ExecutablePath
- C:\windows\System32\Wbem\WMIC.exe
-
复制代码
你会发现有结果有三行,第一行和第二行行尾有若干个空格,还有一个回车符\r,第三行仅有一个回车符。
如果你把wmic process where "Name='WMIC.exe'" get ExecutablePath /value的结果重定向到文件:-
-
- ExecutablePath=C:\windows\System32\Wbem\WMIC.exe
-
-
复制代码
结果有五行,首尾几个空行仅有一个回车符,第三行行尾多一个回车符,即以\r\r\n结尾。
问题就出在多余的\r上,回车符即回到行首,明白了问题所在,出现以下情况也就不足为奇了:- >for /F "delims=" %i in ('wmic process where "Name='WMIC.exe'" get ExecutablePath') do set "p=%i"
-
- " >set "p=ExecutablePath
-
- " >set "p=C:\windows\System32\Wbem\WMIC.exe
-
- " >set "p=
-
- >echo
- ECHO 处于打开状态。
复制代码
那么如何解决这个问题从而正确取值呢?分常用的两种情况,有无/value开关:
一、无/value开关
1、在这种情况下,前面说了,有效行行尾有若干个空格和一个回车符\r,末行有一个回车符。可以用空格分割并舍弃行尾回车符(for /f的默认分隔符就是空格和跳格),用"findstr ."过滤末行回车符(findstr通配符.不匹配\r或\n)- for /f %%i in ('wmic process where "Name='WMIC.exe'" get ExecutablePath ^| findstr .') do set "p=%%i"
- echo %p%
复制代码
2、除了findstr外还有一种方法可以过滤末行回车符- for /f "tokens=2" %%i in ('wmic process where "Name='WMIC.exe'" get Caption^,ExecutablePath') do set "p=%%i"
- echo %p%
复制代码
因为末行只有\r一个字段,没有第二个字段,所以不会取到末行。但还有一种情况(注意tokens):- >for /F "tokens=1-2" %i in ('wmic process where "Name='WMIC.exe'" get Caption,ExecutablePath') do set "p=%%j"
-
- >set "p=ExecutablePath"
-
- >set "p=C:\windows\System32\Wbem\WMIC.exe"
-
- >set "p="
-
- >echo
- ECHO 处于打开状态。
复制代码
它仍然读取了末行,并将末行不存在的第二个字段空值赋给了%%j,与之前不同的是它判断末行第一个字段存在并将\r赋给了%%i。
二、有/value开关
前面说了,在这种情况下,首尾几个空行有一个回车符,有效行行尾多一个回车符,大家一般是这么用的:- for /f "tokens=2 delims==" %%i in ('wmic process where "Name='WMIC.exe'" get ExecutablePath /value') do set "p=%%i"
复制代码
这自然地运用了前面第二种方法排除仅有回车符的空行,然后问题就是去除有效行行尾的回车符,这里介绍几种方法:
1、set不加引号- for /f "tokens=2 delims==" %%i in ('wmic process where "Name='WMIC.exe'" get ExecutablePath /value') do set p=%%i
复制代码
2、使用call
http://www.bathome.net/redirect.php?goto=findpost&pid=265622&ptid=65408
3、for /f处理字符串
http://www.bathome.net/redirect.php?goto=findpost&pid=267090&ptid=65704
如有错漏,还望指教。
作者: lancer 时间: 2023-4-7 16:54
写的很好,仔细拜读了一下,能明白一些了。。。主要是我比较菜,没怎么用过wmic,还是要深入学习一下wmic才行。。。
作者: Five66 时间: 2023-4-7 20:22
貌似新版的ps都不支持传统的wmic了,只有封装wmic的cmdlet....
作者: newswan 时间: 2023-4-8 10:34
回复 3# Five66
嗯, wmic 的输出是有点讨厌
微软的垃圾堆
作者: jorlaying 时间: 2023-4-16 11:16
本帖最后由 jorlaying 于 2023-4-16 11:54 编辑
楼主 按照你的方法遇到一个问题,请看代码,如何解决?- @echo off & setlocal enabledelayedexpansion
- for /f %%i in ('wmic logicaldisk get Description^| findstr .') do set "Description=%%i"
- echo,%Description%
- pause
复制代码
Local Fixed Disk只能读取到Local 空格后面的部分没有了。不能完整显示,set已加引号
还有就是用这个方法,输出的后面都会带一个空格符
作者: buyiyang 时间: 2023-4-16 15:46
回复 5# jorlaying
第一个这个是空白分割符引起的,属性的值是空格分割的,如果值本身有空格就会取错,试试“二、有/value开关”的方法。第二个应该不会有空格吧,因为空格已经作为分割符了。
作者: Batcher 时间: 2023-4-16 17:31
回复 5# jorlaying - @echo off
- for /f "delims=" %%i in ('wmic logicaldisk get Description ^| findstr .') do (
- for %%j in ("%%i") do (
- set "Description=%%~j"
- )
- )
- echo,%Description%
- pause
复制代码
作者: buyiyang 时间: 2023-4-16 23:45
回复 7# Batcher
不过这样%Description%会带有空格。
作者: Batcher 时间: 2023-4-17 10:04
回复 8# buyiyang
是的,这是wmic命令结果里面自己带的空格。
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |