无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 15803|回复: 20
打印 上一主题 下一主题

[已解决] 用批处理FOR命令取出一个多行多列文本文件中某列值赋给变量Vi(i=1..n)并显示的方法

[复制链接]
跳转到指定楼层
1#
发表于 2014-1-7 14:59:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 qj_tzy 于 2014-1-9 22:04 编辑

用批处理FOR命令取出一个多行多列文本文件中某列值赋给变量Vi(i=1..n)的方法

若一文本文件file.txt有多行多列,各列以空格或TAB键分隔,中间有空行,其中某行行首字符存在分号,该行后可能还有无分号打头的行。

现在的问题是:若想取出某列如5列的值,分别赋给变量v1、v2、v3...,忽略空行,取至首个行首字符为分号的行结束,或取满10行结束。若用N表示变量v1、v2、v3中存在有效值的编号个数,即若取到5行有分号则N=4,若取满10行由N=10。现索解取得v1、v2、v3...及N值的批处理,请各位指点,谢谢!

我知道如下批处理只能取最后一个有效行的第5列值赋给变量V:
for /f "eol=; tokens=5 delims= " %%i in (file.txt) do set v=%%i


另有一问:
在批处理中用一句命令取出V%i%(i=1至10)的值,即在上面赋给的值,有几种方法
即:
set i=1至10的某一整数,如4
已知 V%i%(i=1至10)的值,先将其值赋给val,再显示的方法。
set val=V%i%????
echo val=%val%


另:我在2楼和4楼的指导下,编了一段批处理,但在取出第5列值时总是出错,现把该段批处理及所用文本文件上传,请各位帮我调试一下,谢谢。
test.rar (1.41 KB, 下载次数: 19)
2#
发表于 2014-1-8 14:04:56 | 只看该作者
本帖最后由 dos时代菜鸟 于 2014-1-8 14:21 编辑
  1. @echo off && setlocal ENABLEDELAYEDEXPANSION
  2. set n=0
  3. for /f "eol=; tokens=5 delims= " %%i in (x.txt) do (
  4. set /a n=!n!+1
  5. >>%temp%\y.cmd echo set v!n!=%%i
  6. )
复制代码

  1. call %temp%\y.cmd
复制代码




试试这个 吧,我这只是一个思路。可没测试啊!!

点评

在取出第5列值时总是出错,已把该段批处理及所用文本文件上传到1楼,能否帮我调试一下,谢谢!  详情 回复 发表于 2014-1-9 08:59
谢谢您的指点,在您和指导下,我编写如下一段批处理进行测试: @echo off && setlocal enabledelayedexpansion set maxosno=10 set /a maxosno=%maxosno%+1 set syspath=%~dp0 set info_file=%syspath%info_v  详情 回复 发表于 2014-1-8 16:17

评分

参与人数 1无忧币 +5 收起 理由
神的马甲 + 5 厉害厉害

查看全部评分

回复

使用道具 举报

3#
 楼主| 发表于 2014-1-8 16:17:15 | 只看该作者
本帖最后由 qj_tzy 于 2014-1-9 07:38 编辑
dos时代菜鸟 发表于 2014-1-8 14:04
试试这个 吧,我这只是一个思路。可没测试啊!!


现有几点不明:
1.set /a n=n+1 也可用set /a n=!n!+1代替?

2.又如何取出vnamen(n=1....10)的值
因在批处理中,不能直接用vname1、vname2等,而是要取出 n=指定值如4对应的vnamen的值。
回复

使用道具 举报

4#
发表于 2014-1-8 20:34:37 | 只看该作者
这样可以不?
  1. @echo off & setlocal enabledelayedexpansion
  2. set n=0
  3. for /f "tokens=1,5eol=" %%a in (a.txt) do (
  4.     set "str=%%a"
  5.     if "!str:~,1!" == ";" (
  6.         goto :Next
  7.     ) else (
  8.         if !n! lss 10 (set /a n+=1&set "V!n!=%%b") else goto :Next
  9.     )
  10. )

  11. :Next
  12. for /l %%a in (1 1 %n%) do echo,V%%a=!V%%a!
  13. pause
复制代码

点评

在取出第5列值时总是出错,已把该段批处理及所用文本文件上传到1楼,能否帮我调试一下,谢谢!  详情 回复 发表于 2014-1-9 07:46
我已测试正常,非常感谢!  详情 回复 发表于 2014-1-8 22:20

评分

参与人数 1无忧币 +5 收起 理由
神的马甲 + 5 太赞了

查看全部评分

回复

使用道具 举报

5#
 楼主| 发表于 2014-1-8 22:20:53 | 只看该作者
本帖最后由 qj_tzy 于 2014-1-8 22:22 编辑


我复制上楼代码,已修正测试正常,非常感谢!
回复

使用道具 举报

6#
 楼主| 发表于 2014-1-9 07:46:37 | 只看该作者

在取出第5列值时总是出错,已把该段批处理及所用文本文件上传到1楼,能否帮我调试一下,谢谢!
回复

使用道具 举报

7#
 楼主| 发表于 2014-1-9 08:59:44 | 只看该作者
dos时代菜鸟 发表于 2014-1-8 14:04
试试这个 吧,我这只是一个思路。可没测试啊!!

在取出第5列值时总是出错,已把该段批处理及所用文本文件上传到1楼,能否帮我调试一下,谢谢!

点评

是这种效果吗? 分割特征要把制表符加上,因为你的文本里面包含制表符  详情 回复 发表于 2014-1-9 09:21
回复

使用道具 举报

8#
发表于 2014-1-9 09:21:53 | 只看该作者
qj_tzy 发表于 2014-1-9 08:59
在取出第5列值时总是出错,已把该段批处理及所用文本文件上传到1楼,能否帮我调试一下,谢谢!

getinfo1.rar (1.14 KB, 下载次数: 16)

是这种效果吗?

分割特征要把制表符加上,因为你的文本里面包含制表符

点评

感谢您及dos时代菜鸟的指点,是否可这样理解: 因文本文件是同时以TAB制表符键和空格键分隔的 ,"delims= "中的空格,就要同时包括一个TAB键位和一个空格位。是吗?  详情 回复 发表于 2014-1-9 11:54
回复

使用道具 举报

9#
发表于 2014-1-9 11:25:48 | 只看该作者
把你文本文件中的 tab键 都换成 空格。

点评

把文本文件中的tab键都换成空格,批处理中的分隔符也相应作更改后,第6列的值是第5列的值,不知为何?  详情 回复 发表于 2014-1-9 12:37
回复

使用道具 举报

10#
 楼主| 发表于 2014-1-9 11:54:48 | 只看该作者
本帖最后由 qj_tzy 于 2014-1-9 13:18 编辑
神的马甲 发表于 2014-1-9 09:21
是这种效果吗?

分割特征要把制表符加上,因为你的文本里面包含制表符


感谢您及dos时代菜鸟的指点,是否可这样理解:
因文本文件是同时以TAB制表符键和空格键分隔的 ,"delims=         "中的空格,就要同时包括一个TAB键位和一个空格位。

后又测试,好似那么把文本文件的TAB键全部换为空格键,那么空格键全部换为TAB键,在文本文件编辑中,难道不能同时使用TAB键和空格吗,若这样,岂不是有违编辑的常规吗
有无同时使用TAB键和空格的解决办法

我又作了测试,无论TAB键全部换为空格键,或者空格键全部换为TAB键,批处理中的分隔符也相应作更改后,最后一列即第7列的值是第6列的值,不知为何?
回复

使用道具 举报

11#
 楼主| 发表于 2014-1-9 12:37:37 | 只看该作者
本帖最后由 qj_tzy 于 2014-1-9 13:18 编辑
dos时代菜鸟 发表于 2014-1-9 11:25
把你文本文件中的 tab键 都换成 空格。


把文本文件中的tab键都换成空格,批处理中的分隔符也相应作更改后,最后一列即第7列的值是第6列的值,不知为何?
回复

使用道具 举报

12#
发表于 2014-1-9 12:39:02 | 只看该作者
tab和空格都是for默认的分隔符,不加delims选项就可以了
真心没明白楼主的意思。以顶楼所给附件为例,楼主想要显示成什么样的效果呢?

点评

我不加delims选项又作了测试,也是最后一列即第7列的值是第6列的值,这就怪了  详情 回复 发表于 2014-1-9 13:19
谢谢指点,我试试!  详情 回复 发表于 2014-1-9 12:59
回复

使用道具 举报

13#
 楼主| 发表于 2014-1-9 12:59:05 | 只看该作者
pznpt 发表于 2014-1-9 12:39
tab和空格都是for默认的分隔符,不加delims选项就可以了
真心没明白楼主的意思。以顶楼所给附件为例,楼主 ...

谢谢指点,我试试!
回复

使用道具 举报

14#
 楼主| 发表于 2014-1-9 13:19:59 | 只看该作者
pznpt 发表于 2014-1-9 12:39
tab和空格都是for默认的分隔符,不加delims选项就可以了
真心没明白楼主的意思。以顶楼所给附件为例,楼主 ...

我不加delims选项又作了测试,也是最后一列即第7列的值是第6列的值,这就怪了

点评

仔细揣摩你的意图,是不是想这样?  详情 回复 发表于 2014-1-9 16:29
回复

使用道具 举报

15#
发表于 2014-1-9 16:29:42 | 只看该作者
qj_tzy 发表于 2014-1-9 13:19
我不加delims选项又作了测试,也是最后一列即第7列的值是第6列的值,这就怪了

仔细揣摩你的意图,是不是想这样?
  1. @echo off & setlocal enabledelayedexpansion
  2. set "file=%~dp0info_vhd_sys_old.flg"
  3. set n=0
  4. for /f "usebackq tokens=1-7eol=" %%a in ("%file%") do (
  5.     set "str=%%a"
  6.     if "!str:~,1!" == ";" (
  7.         goto :Next
  8.     ) else (
  9.         set /a n+=1
  10.         set "vname!n!=%%a" & set "vdsk!n!=%%b" & set "vdir!n!=%%c"
  11.         set "monvhd!n!=%%d" & set "subvhd!n!=%%e"
  12.         set "bakvhd!n!=%%f" & set "tmpvhd!n!=%%g"
  13.     )
  14. )

  15. :Next
  16. for %%a in (vname vdsk vdir monvhd subvhd bakvhd tmpvhd) do (
  17.     for /l %%b in (1 1 %n%) do echo,%%a%%b=!%%a%%b!
  18.     echo,
  19. )
  20. pause
复制代码

点评

我复制了上楼代码进行测试,完全达到了我的要求,非常感谢!  详情 回复 发表于 2014-1-9 17:12

评分

参与人数 1无忧币 +5 收起 理由
神的马甲 + 5 赞一个!

查看全部评分

回复

使用道具 举报

16#
 楼主| 发表于 2014-1-9 17:12:00 | 只看该作者
pznpt 发表于 2014-1-9 16:29
仔细揣摩你的意图,是不是想这样?

我复制了上楼代码进行测试,完全达到了我的要求,非常感谢!
回复

使用道具 举报

17#
发表于 2014-1-13 17:45:25 | 只看该作者
虽然看不懂楼上兄弟的代码,但觉得很有意思,趁机学习了一下批处理,似乎还能这样:

  1. @echo off & setlocal enabledelayedexpansion
  2. set "file=%~dp0info_vhd_sys_old.flg"
  3. set n=0
  4. for /f "usebackq tokens=1-7 eol=;" %%a in ("%file%") do (
  5.         set /a n+=1
  6.         set "vname!n!=%%a" & set "vdsk!n!=%%b" & set "vdir!n!=%%c"
  7.         set "monvhd!n!=%%d" & set "subvhd!n!=%%e"
  8.         set "bakvhd!n!=%%f" & set "tmpvhd!n!=%%g"
  9. )

  10. for %%a in (vname vdsk vdir monvhd subvhd bakvhd tmpvhd) do (
  11.     for /l %%b in (1 1 %n%) do echo,%%a%%b=!%%a%%b!
  12.     echo,
  13. )
  14. pause
复制代码

点评

eol=; 是忽略以分号开头的行,如果分号下面还有其它行的话,“取至首个行首字符为分号的行结束”就不成立了。呵呵  详情 回复 发表于 2014-1-13 23:37
我已把pznpt及您指点的批处理写入了我的一个事务处理中,再次表示衷心感谢!  详情 回复 发表于 2014-1-13 18:06
回复

使用道具 举报

18#
 楼主| 发表于 2014-1-13 18:06:47 | 只看该作者
神的马甲 发表于 2014-1-13 17:45
虽然看不懂楼上兄弟的代码,但觉得很有意思,趁机学习了一下批处理,似乎还能这样:

我已把pznpt及您指点的批处理写入了我的一个事务处理中,再次表示衷心感谢!
回复

使用道具 举报

19#
发表于 2014-1-13 23:37:41 | 只看该作者
神的马甲 发表于 2014-1-13 17:45
虽然看不懂楼上兄弟的代码,但觉得很有意思,趁机学习了一下批处理,似乎还能这样:

eol=; 是忽略以分号开头的行,如果分号下面还有其它行的话,“取至首个行首字符为分号的行结束”就不成立了。呵呵

点评

在您及神的马甲的指点下,因还要取满10行退出,我将其调整为: @echo off & setlocal enabledelayedexpansion set "file=%~dp0info_vhd_sys_old.flg" if not exist %file% goto :nofile set maxosno=10 & set n=  详情 回复 发表于 2014-1-13 23:59
哦,原来是这样,还是你考虑比较周全,哈哈  详情 回复 发表于 2014-1-13 23:44
回复

使用道具 举报

20#
发表于 2014-1-13 23:44:15 | 只看该作者
pznpt 发表于 2014-1-13 23:37
eol=; 是忽略以分号开头的行,如果分号下面还有其它行的话,“取至首个行首字符为分号的行结束”就不成立 ...

哦,原来是这样,还是你考虑比较周全,哈哈
回复

使用道具 举报

21#
 楼主| 发表于 2014-1-13 23:59:16 | 只看该作者
pznpt 发表于 2014-1-13 23:37
eol=; 是忽略以分号开头的行,如果分号下面还有其它行的话,“取至首个行首字符为分号的行结束”就不成立 ...

在您及神的马甲的指点下,因还要取满10行退出,我将其调整为:
@echo off & setlocal enabledelayedexpansion
set "file=%~dp0info_vhd_sys_old.flg"
if not exist %file% goto :nofile
set maxosno=10 & set n=0
for /f "usebackq tokens=1-7 eol= delims=  " %%a in ("%file%") do (
   set "str=%%a"
   if "!str:~,1!" == ";" (goto :Next) else (
if !n! lss %maxosno% (
         set /a n+=1
         set "vname!n!=%%a" & set "vdsk!n!=%%b" & set "vdir!n!=%%c"
         set "monvhd!n!=%%d" & set "subvhd!n!=%%e"
         set "bakvhd!n!=%%f" & set "tmpvhd=%%g"
         for %%i in (NO No nO no) do if "!tmpvhd!"=="%%i" set "tmpvhd="
  set "tmpvhd!n!=!tmpvhd!"
   ) else (goto :Next)   
)
)

:Next
for %%a in (vname vdsk vdir monvhd subvhd bakvhd tmpvhd) do (
    for /l %%b in (1 1 %n%) do echo,%%a%%b=!%%a%%b!
    echo,
)
pause
goto end
:nofile
echo. & echo.未找到信息文件,按任一键退出.... & echo. & pause
goto end
:end
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-11-27 06:12

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表