Board logo

标题: [文本处理] 批处理怎样把第2,3,4列数据均除以1000? [打印本页]

作者: srj092005    时间: 2014-8-31 22:29     标题: 批处理怎样把第2,3,4列数据均除以1000?

1.BAT程序处理的数据行有限吗?我的一个文件有一千多行,但是每次处理都不能全部处理完,并且每次处理感觉原来越少,为什么?
2.我想提取这个文件中的前四列数据,并且第2,3,4列数据均除以1000,代码该怎么编写?
在此膜拜,感激不尽!
数据形式
  NODE        X           Y           Z         THXY    THYZ    THZX
        1   -102.78     -36.700     0.50070        0.00    0.00    0.00
        2   -116.16     -1.7202      1.4883        0.00    0.00    0.00
        3   -111.74     -31.270      1.4883        0.00    0.00    0.00
        4   -93.983     -31.638      3.1759        0.00    0.00    0.00
        5   -93.860     -30.427      3.2524        0.00    0.00    0.00
        6   -93.711     -30.387      3.2838        0.00    0.00    0.00
        7   -93.743     -29.214      3.3279        0.00    0.00    0.00
        8   -93.435     -29.134      3.3925        0.00    0.00    0.00
        9   -93.631     -28.001      3.4025        0.00    0.00    0.00
       10   -93.526     -26.786      3.4763        0.00    0.00    0.00
作者: DAIC    时间: 2014-9-1 09:53

但是每次处理都不能全部处理完,并且每次处理感觉原来越少,为什么?

把你的代码发出来看看
作者: terse    时间: 2014-9-1 09:57

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1-4*" %%a in (a.txt) do (
  3.     if defined str (
  4.        set $1=%%b&set $2=%%c&set $3=%%d
  5.        for /l %%I in (1,1,3) do (
  6.            for /f "tokens=1* delims=." %%i in ("!$%%I!") do (
  7.                set s=%%i
  8.                if "!s:~,1!" == "-" (set b=-) else set b=
  9.                set s=00000!s:-=!
  10.                for /f "tokens=* delims=0" %%m in ("!s:~,-4!.!s:~-4!") do set $%%I=%%m%%j
  11.                if "!$%%I:~,1!" == "." (set $%%I=!b!0!$%%I!) else set $%%I=!!b!!$%%I!
  12.            )
  13.        )
  14.        set str=%%a !$1! !$2! !$3! %%e
  15.     ) else set str=%%a %%b %%e %%d %%e
  16.       echo !str!
  17. )
  18. pause
复制代码

作者: neorobin    时间: 2014-9-1 12:05

本帖最后由 neorobin 于 2014-9-2 20:12 编辑
  1. @echo off & setlocal enabledelayedexpansion
  2. for /f "tokens=1-4" %%a in (a.txt) do (
  3. if /i "%%a"=="NODE" (
  4. echo %%a %%b %%c %%d
  5. ) else (
  6. for %%A in (%%b %%c %%d) do (
  7. for /f "tokens=1-2 delims=." %%p in ("%%A") do (
  8. set "L=%%p" & set "N=00!L:-=!"
  9. set /a "M=!L:-=!/1000,L>>=31"
  10. set "s=!s! !L:~0,-1!!M!.!N:~-3!%%q"
  11. )
  12. )
  13. echo %%a !s!& set "s="
  14. )
  15. )
  16. pause
复制代码

作者: srj092005    时间: 2014-9-1 16:48

本帖最后由 srj092005 于 2014-9-1 16:54 编辑

回复 2# DAIC
  1.     @echo off
  2. for /f "tokens=7-8 delims=, " %%a in (13ELIST.lis) do (
  3. echo e,%%a,%%b
  4. )
  5. pause
复制代码
这个代码是取另一个文件的7-8列数据,共1033行,第一次处理只能取到500-1033行左右,请大神指教。
作者: srj092005    时间: 2014-9-1 17:36

回复 3# terse
大神您好,想再问一下代码在哪里体现出了数据除以1000这个概念,比如说我以后想乘以100啊之类,直接在这个模式上改变,还有就是最后的格式,我想存储为
n,10000,10000,10000  这样的形式该怎么处理呢?
作者: srj092005    时间: 2014-9-1 17:54

本帖最后由 srj092005 于 2014-9-1 17:55 编辑

回复 4# neorobin


    大神您好,想再问一下代码在哪里体现出了数据除以1000这个概念,比如说我以后想乘以100啊之类,直接在这个模式上改变,还有就是最后的格式,我想存储为
n,10000,10000,10000  这样的形式该怎么处理呢?我改成了这样 echo,%%a,!s!&,set "s="然后就和结果不一样了,然后想把前面IF的那个形式变为直接删除此类行,大神怎么解?
作者: neorobin    时间: 2014-9-1 20:08

本帖最后由 neorobin 于 2014-9-2 20:11 编辑

回复 7# srj092005
cmd 不支持小数运算, 所以没有非常简单直接的方式

关键在第 8-10 行的处理, 举例:
数据: -93.526

第 7 行中 delims=.  将其以 . 为分界符分为两部分 -93  和  526

第 8 行中 00!L:-=! 为整数部分插入若干前缀 0 , 此处要求 除以 1000(=10^3) 所以至少 插入 2 (=3-1) 个 0,   93 就变成 0093

第 9 行 M=!L:-=!/1000, 取整数部分的绝对值除以 1000, 这个除法不会保留精确商的小数部分, 小数部分由第 7, 8 行保留
L>>=31 得到数据的符号, 负数 得到 -1, 否则得到 0

第 10 行:  !L:~0,-1!!M!.!N:~-3!%%q  
!L:~0,-1! 取符号,   !M! 得到数据除以 1000 后的整数部分, !N:~-3! 是取  00-0093 的最后 3 位 093,
%%q 得到 第 7 行分解出来的原小数部分 526,  结果数据就是 -0.093526

第 13 行, 不要在 & 后加 , 号

如果要变成除以 100, 第 8 行中两处 2 个 0 仍然可用 (2 > 1), 因为至少各只需 1 个 0 就行了, 如果是要除以 10000, 0 的个数 就必须增加了.
第 9 行 1000 改成 100 即可, 第 10 行 !N:~-3! 中 3 就要改成 2, 如果 除数是其他 10 的 n 次方, 以此类推.

如果要以 , 号为分隔符输出,
第 10 行改为
  1. set "s=!s!,!L:~0,-1!!M!.!N:~-3!%%q"
复制代码
第 13 行改为
  1. echo %%a,!s!& set "s="
复制代码
标题行是首行, 可以将第 2 行改为
  1. for /f "tokens=1-4 skip=1" %%a in (a.txt) do (
复制代码
将第 1 行跳过
作者: DAIC    时间: 2014-9-2 12:39

回复 5# srj092005


    把13ELIST.lis压缩一下,传上来,我试试。
作者: srj092005    时间: 2014-9-2 13:33

本帖最后由 srj092005 于 2014-9-2 13:38 编辑

回复 8# neorobin


    多谢大神指教,还有就是他处理的数据是不是有限?1033行的数据只显示了500多行。能加您QQ吗?
作者: srj092005    时间: 2014-9-2 13:36

回复 9# DAIC


    用这个文件试一试,有1033行,任取哪几列都可以,弹出的窗口会显示从1到1033,但是最后只有500多到1033左右。
作者: neorobin    时间: 2014-9-2 14:02

本帖最后由 neorobin 于 2014-9-2 20:13 编辑

回复 10# srj092005

CMD 的窗口缓冲区 行数 和 列数 都是有限制的, 你可以用 MODE 命令 查看

有大量文本输出时, 把输出定向到文件, 不要在窗口中截取
  1. @echo off & setlocal enabledelayedexpansion
  2. >R.txt (
  3. for /f "tokens=1-5 delims=," %%a in (node.txt) do (
  4. for %%A in (%%c %%d %%e) do (
  5. for /f "tokens=1-2 delims=." %%p in ("%%A") do (
  6. set "L=%%p" & set "N=00!L:-=!"
  7. set /a "M=!L:-=!/1000,L>>=31"
  8. set "s=!s!,!L:~0,-1!!M!.!N:~-3!%%q"
  9. )
  10. )
  11. echo %%a,%%b!s!& set "s="
  12. )
  13. )
  14. start R.txt
  15. pause
复制代码

作者: terse    时间: 2014-9-2 16:07

回复 12# neorobin
这里第7行 "N=00!L:-=-00!" 和 "N=00!L:-=!" 没区别吧 一时没看懂意思
作者: neorobin    时间: 2014-9-2 20:07

回复 13# terse

确实, 我写得多余了, 只需 N=00!L:-=! 就行了
作者: srj092005    时间: 2014-9-3 11:02

回复 14# neorobin


    大神我想学批处理,但是没门道,怎么学习这些代码编写啊?之前大学时学了一些C++,但是都忘光了····
作者: srj092005    时间: 2014-9-3 11:11

回复  srj092005
cmd 不支持小数运算, 所以没有非常简单直接的方式

关键在第 8-10 行的处理, 举例:
数 ...
neorobin 发表于 2014-9-1 20:08


其实不仅仅是标题行是这样,中间每隔20行数据就会出现一行与标题行一样的,但是取用的时候不需要,所以我就每次只能手动删除。代码可以实现不取这样的行吗?
作者: srj092005    时间: 2014-9-3 11:13

回复 8# neorobin


    其实不仅仅是标题行,中间每隔20行数据都会出现与标题行一样的,所以每次我取完数据后都得手动删除,能用代码实现取数据时就删掉这样的非数据行吗?
作者: neorobin    时间: 2014-9-3 11:17

回复 15# srj092005

微软提供了 帮助文件, 此帖有下载页链接

http://www.bathome.net/viewthrea ... mp;highlight=NTCMDS

此论坛的 教程&资料 区有许多文章, 其中有些知识及技巧甚至是官方帮助文件中未提及的

此论坛的许多精华帖及加分帖,挑战题等可以提供一些更深入精进学习的资源
作者: neorobin    时间: 2014-9-3 11:20

回复 17# srj092005

在 4  楼代码中保留  if /i "%%a"=="NODE" (  ,  过滤掉那些非数据行就行了
作者: DAIC    时间: 2014-9-3 12:43

回复 15# srj092005


http://bbs.bathome.net/thread-75-1-1.html




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