Board logo

标题: [文本处理] 【已解决】批处理中变量的字符截取怎么与看到的不符 [打印本页]

作者: flyingsand    时间: 2009-3-25 16:37     标题: 【已解决】批处理中变量的字符截取怎么与看到的不符

虽然代码是网络方面的,但问题好像是文本处理方面的,希望没发错。
最近我做了个获取网络连接名称的批处理,之前用%jk::=%来删掉冒号,没问题,后来想换成截取的办法,竟然和看到的不符,看代码吧,加双引号是为了证明变量前后没空格和其他字符,不加也一样截取不符。怎么回事?
  1. @echo off
  2. for /f "tokens=1-2,*" %%i in ('ipconfig^|find /i "Ethernet adapter"') do set jk=%%k
  3. echo "%jk%"
  4. echo "%jk::=%"
  5. echo "%jk:~0,-1%"
  6. echo "%jk:~0,-2%"
  7. set jk=%jk%
  8. echo "%jk:~0,-1%"
  9. pause
复制代码
假设我的网络连接名字是:本地连接 测试,运行后结果竟然是

"本地连接 测试:"
"本地连接 测试"
"本地连接 测试:"
"本地连接 测试"
"本地连接 测试"

文字看不清,贴下图

[ 本帖最后由 flyingsand 于 2009-3-25 19:41 编辑 ]
作者: 随风    时间: 2009-3-25 17:30

到底有何不同?你没有说明啊,这种问题,最好把'ipconfig^|find /i "Ethernet adapter的结果定向到文本中,再帖出文本内容,并且说明你希望的结果和实际结果。
作者: 随风    时间: 2009-3-25 17:48

仔细看了下,应该是有个不可见字符。这样就可以了。
for /f "tokens=1,2*" %%i in ('ipconfig^|find /i "Ethernet adapter"') do call set "jk=%%k"
作者: flyingsand    时间: 2009-3-25 18:09

你看下代码,对比下ipconfig和代码的结果就知了,我贴下吧。
ipconfig^|find /i "Ethernet adapter"的结果重定向到文本[attach]1084[/attach]
我是想取得网络连接的名字“本地连接 测试”(没冒号),已成功,但有些疑问。
第一句for截取后,设变量jk为本地连接 测试:这里有冒号)
第二句显示变量,第三句删冒号,没问题
第四句echo "%jk:~0,-1%"这是取变量jk除最后一个字符的吧,但结果是本地连接 测试:这里有冒号)
第五句echo "%jk:~0,-2%"这是取变量jk除最后两个字符的吧,但结果是本地连接 测试(这里没冒号)
第六句set jk=%jk%
第七句echo "%jk:~0,-1%"这和第四句一样,请注意前一句变量的值并没变,但结果和第四句不同,是本地连接 测试(这里没冒号)

不知这次可否说清楚了

作者: flyingsand    时间: 2009-3-25 18:13

原帖由 随风 于 2009-3-25 17:48 发表
仔细看了下,应该是有个不可见字符。这样就可以了。
for /f "tokens=1,2*" %%i in ('ipconfig^|find /i "Ethernet adapter"') do call set "jk=%%k"

晕,不可见字符,
还真正常了
作者: flyingsand    时间: 2009-3-25 18:23

又想了一下,为什么,第一个set的变量能包括不可见字符
set jk=%jk%这个就没包括了呢
作者: flyingsand    时间: 2009-3-25 19:40

对call set "jk=%%k"不会包括不可见字符,不是很理解,又修改了下,绕过了不可见字符,只是数了17个字符,很不爽。
问题算是解决了吧,如果谁对这个问题或不可见字符有新的见解,请跟帖。
  1. @echo off
  2. for /f "delims=:" %%i in ('ipconfig^|find /i "Ethernet adapter"') do set jk=%%i
  3. echo "%jk:~17%"
  4. pause
复制代码

作者: Batcher    时间: 2009-3-25 20:32     标题: 回复 4楼 的帖子

“本地连接”和“测试”中间那个字符不是空格,而是特殊字符(用十六进展编辑器打开看看就知道了),你从哪里复制来的?为何一定要这样命名本地连接?
作者: flyingsand    时间: 2009-3-25 21:36

原帖由 Batcher 于 2009-3-25 20:32 发表
“本地连接”和“测试”中间那个字符不是空格,而是特殊字符(用十六进展编辑器打开看看就知道了),你从哪里复制来的?为何一定要这样命名本地连接?

中文状态下按空格输入的,只是想说明网络连接的名字可以有空格等的,这样用for的时候就不能直接"tokens=3",不是这个原因吧,把空格去掉也一样啊
作者: Batcher    时间: 2009-3-25 21:40     标题: 回复 9楼 的帖子

因为以这个中文空格是全角的,你换个中文半角空格就行了。
for命令的默认列分隔符里面是不包含全角空格的。
作者: flyingsand    时间: 2009-3-25 21:45

把空格去掉一样啊
你的没改过吧,运行一楼的代码看下
作者: Batcher    时间: 2009-3-25 21:45

另外,在本机网络情况比较复杂的情况下,截取ipconfig的命令返回结果来获取本地连接的方法可能会出现错误。
这里有另外一个思路,可以参考一下:
http://bbs.bathome.net/viewthread.php?tid=1689
作者: flyingsand    时间: 2009-3-25 22:09

什么复杂情况,是指多网卡吗?我本来就是做双网卡的,之前是用netsh interface ip show address命令的,但速度比不上ipconfig就用这个了,你那个暂时看不懂
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set jk1=0
  4. set jk2=0
  5. for /f "delims=:" %%a in ('ipconfig^|find /i "Ethernet adapter"') do (
  6. if !jk1!==0 (set jk1=%%a) else set jk2=%%a
  7. )
  8. echo %jk1:~17%
  9. echo %jk2:~17%
  10. pause
复制代码

作者: Batcher    时间: 2009-3-25 22:28     标题: 回复 13楼 的帖子

对于安装了VM的用户,可能同时开启了多块虚拟网卡,再加上本机物理网卡,要想写出比较通用就会变得比较复杂。
可以在代码中先判断一下有几块网卡^_^
作者: flyingsand    时间: 2009-3-25 22:33

你的还没适用双网卡啊。
回到1楼的代码和我4楼的说明,运行后第三行结果应该是没冒号的(和网络连接名称没关),但实际是有,就算是系统默认的名称“本地连接”也是一样,运行一次就知了。
作者: Batcher    时间: 2009-3-25 22:35     标题: 回复 15楼 的帖子

是的,我说的只是思路。
不管那种方法,只要考虑问题全面了,别说双网卡,十个网卡都一样能通用:)
作者: flyingsand    时间: 2009-3-25 22:37

原帖由 Batcher 于 2009-3-25 22:28 发表
对于安装了VM的用户,可能同时开启了多块虚拟网卡,再加上本机物理网卡,要想写出比较通用就会变得比较复杂。
可以在代码中先判断一下有几块网卡^_^

通用是有点麻烦,我双网卡的代码,第二个有点取巧
作者: Batcher    时间: 2009-3-25 22:51     标题: 回复 17楼 的帖子

多网卡可以这样:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set count=0
  4. for /f "delims=:" %%a in ('ipconfig^|find /i "Ethernet adapter"') do (
  5.   set /a count+=1
  6.   call :GetName "%%a" !count!
  7. )
  8. for /f "tokens=2 delims==" %%a in ('set LocalConn_') do (
  9.   echo.%%a
  10. )
  11. goto :eof
  12. :GetName
  13. set "str=%1"
  14. set LocalConn_%2=%str:~18,-1%
复制代码

作者: flyingsand    时间: 2009-3-25 23:13

原帖由 Batcher 于 2009-3-25 22:51 发表
多网卡可以这样:@echo off
setlocal enabledelayedexpansion
set count=0
for /f "delims=:" %%a in ('ipconfig^|find /i "Ethernet adapter"') do (
  set /a count+=1
  call :GetName "%%a" !count!
)
fo ...

感谢提供通用代码(orz评分时打错字了)
现在只剩下那个所谓的不可见字符问题了




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2