无忧启动论坛

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

作者: qj_tzy    时间: 2014-1-7 14:59
标题: 用批处理FOR命令取出一个多行多列文本文件中某列值赋给变量Vi(i=1..n)并显示的方法
本帖最后由 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)

作者: dos时代菜鸟    时间: 2014-1-8 14:04
本帖最后由 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
复制代码




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


作者: qj_tzy    时间: 2014-1-8 16:17
本帖最后由 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的值。

作者: pznpt    时间: 2014-1-8 20:34
这样可以不?
  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
复制代码

作者: qj_tzy    时间: 2014-1-8 22:20
本帖最后由 qj_tzy 于 2014-1-8 22:22 编辑
pznpt 发表于 2014-1-8 20:34
这样可以不?


我复制上楼代码,已修正测试正常,非常感谢!
作者: qj_tzy    时间: 2014-1-9 07:46
pznpt 发表于 2014-1-8 20:34
这样可以不?

在取出第5列值时总是出错,已把该段批处理及所用文本文件上传到1楼,能否帮我调试一下,谢谢!
作者: qj_tzy    时间: 2014-1-9 08:59
dos时代菜鸟 发表于 2014-1-8 14:04
试试这个 吧,我这只是一个思路。可没测试啊!!

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

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

是这种效果吗?

分割特征要把制表符加上,因为你的文本里面包含制表符
作者: dos时代菜鸟    时间: 2014-1-9 11:25
把你文本文件中的 tab键 都换成 空格。
作者: qj_tzy    时间: 2014-1-9 11:54
本帖最后由 qj_tzy 于 2014-1-9 13:18 编辑
神的马甲 发表于 2014-1-9 09:21
是这种效果吗?

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


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

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

我又作了测试,无论TAB键全部换为空格键,或者空格键全部换为TAB键,批处理中的分隔符也相应作更改后,最后一列即第7列的值是第6列的值,不知为何?
作者: qj_tzy    时间: 2014-1-9 12:37
本帖最后由 qj_tzy 于 2014-1-9 13:18 编辑
dos时代菜鸟 发表于 2014-1-9 11:25
把你文本文件中的 tab键 都换成 空格。


把文本文件中的tab键都换成空格,批处理中的分隔符也相应作更改后,最后一列即第7列的值是第6列的值,不知为何?
作者: pznpt    时间: 2014-1-9 12:39
tab和空格都是for默认的分隔符,不加delims选项就可以了
真心没明白楼主的意思。以顶楼所给附件为例,楼主想要显示成什么样的效果呢?
作者: qj_tzy    时间: 2014-1-9 12:59
pznpt 发表于 2014-1-9 12:39
tab和空格都是for默认的分隔符,不加delims选项就可以了
真心没明白楼主的意思。以顶楼所给附件为例,楼主 ...

谢谢指点,我试试!
作者: qj_tzy    时间: 2014-1-9 13:19
pznpt 发表于 2014-1-9 12:39
tab和空格都是for默认的分隔符,不加delims选项就可以了
真心没明白楼主的意思。以顶楼所给附件为例,楼主 ...

我不加delims选项又作了测试,也是最后一列即第7列的值是第6列的值,这就怪了
作者: pznpt    时间: 2014-1-9 16:29
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
复制代码

作者: qj_tzy    时间: 2014-1-9 17:12
pznpt 发表于 2014-1-9 16:29
仔细揣摩你的意图,是不是想这样?

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

作者: 神的马甲    时间: 2014-1-13 17:45
虽然看不懂楼上兄弟的代码,但觉得很有意思,趁机学习了一下批处理,似乎还能这样:

  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
复制代码

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

我已把pznpt及您指点的批处理写入了我的一个事务处理中,再次表示衷心感谢!
作者: pznpt    时间: 2014-1-13 23:37
神的马甲 发表于 2014-1-13 17:45
虽然看不懂楼上兄弟的代码,但觉得很有意思,趁机学习了一下批处理,似乎还能这样:

eol=; 是忽略以分号开头的行,如果分号下面还有其它行的话,“取至首个行首字符为分号的行结束”就不成立了。呵呵
作者: 神的马甲    时间: 2014-1-13 23:44
pznpt 发表于 2014-1-13 23:37
eol=; 是忽略以分号开头的行,如果分号下面还有其它行的话,“取至首个行首字符为分号的行结束”就不成立 ...

哦,原来是这样,还是你考虑比较周全,哈哈
作者: qj_tzy    时间: 2014-1-13 23:59
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





欢迎光临 无忧启动论坛 (http://bbs.wuyou.net/) Powered by Discuz! X3.3