[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] [已解决]批处理如何对含科学计数数字的txt批量修改?

我有如下内容的大量txt文件
2.0000000000000001e-001
0.0000000000000000e+000
0.0000000000000000e+000
-2.0000000000000001e-001
1.6695009999999998e+005
2.8049900000000001e+004
需要对科学计数改为正常数字,即如下
0.2
0
0
-0.2
166950.09999999998
28049.900000000001

[ 本帖最后由 alexwxcong 于 2010-5-2 20:30 编辑 ]
1

评分人数

    • Batcher: 感谢主动给标题标注[已解决]字样PB + 2

  1. @echo off&setlocal enabledelayedexpansion
  2. set "l=0000000000"
  3. for /f "tokens=1,2 delims=e" %%i in (a.txt) do (
  4.     set "str=%%i"
  5.     if "%%j" neq "" (
  6.     set /a "i=%%j%%1000"
  7.     if !i! neq 0 (
  8.     if !i! lss 0 (
  9.     for /f "tokens=1,2 delims=." %%a in ("%%i") do (
  10.         set "str=%%a"
  11.         if %%a lss 0 (set j=-0.)else set "j=0."
  12.         set "str=%l%!str:-=!"
  13.         set "b=%%b"
  14.         for %%c in (!i!) do set "str=!j!!str:~%%c!!b:~,%%c!"
  15.         )
  16.         ) else (
  17.           for /f "tokens=1,2 delims=." %%a in ("%%i") do (
  18.               set "str=%%b"
  19.               for %%c in (!i!) do set "str=%%a!str:~,%%c!.!str:~%%c!"
  20.         )
  21.       )
  22.     )
  23.   )
  24.           if "!str:0=!" neq "." (echo !str!)else echo 0
  25. )
  26. pause
复制代码

TOP

根据楼主要求:
1,移位数字范围为000到015
2,允许科学记数与普通数字(非16进制)混排
3,100行测试,运行时间小于0.08秒
4,所有科学记数转换的数字只精确到小数8位(未使用4舍5入)
5,对于小于0.00000001的数字,精确到0.00000001
  1. @echo off
  2. for %%a in (*.txt) do (
  3. (for /f "usebackq delims=" %%b in ("%%a") do (
  4.       setlocal enabledelayedexpansion
  5.       set b=%%b
  6.       if !b:~18^,1!==e set a==
  7.       if !b:~19^,1!==e set a==
  8.       if not defined a (echo.%%b) else (
  9.             for /f "tokens=1,2* delims=e." %%c in ("%%b") do (
  10.                   set c=%%c&set d=%%d&set e=%%e&set f=!e:~2!
  11.                   if !f:~0^,1!==0 set f=!f:~1!
  12.                   if !c:~0^,1!==- set g=-&set c=!c:~1!
  13.                   if !c:~0^,1!==0 (echo.0) else (
  14.                   set h=!c!!d!
  15.                   if !e:~0^,1!==+ (
  16.                   set/a f+=1&for %%f in (!f!) do set h=!h:~0,%%f!.!h:~%%f!
  17.                   ) else (
  18.                   set/a f-=1&for /l %%f in (1,1,!f!) do set i=!i!0
  19.                   set h=0.!i!!h!
  20.                   )
  21.                   for /f "tokens=1* delims=." %%f in ("!h!") do set f=%%g&set h=%%f.!f:~0,8!
  22.                   if !h!==0.00000000 set h=0.00000001
  23.                   if not "!h:.=!"=="!h!" set "h=!h:0= !"&set "h=!h:.=#!"&for /f "delims=" %%f in ("!h!") do set h=%%~ff&set "h=!h:%cd%\=!"&set "h=!h:#=.!"&set "h=!h: =0!"
  24.                   if !h:~-1!==. set h=!h:~0,-1!
  25.             echo.!g!!h!)))
  26.       endlocal))>"%%a_"
  27. del /q "%%a"
  28. ren "%%a_" "%%a")
复制代码
结贴时,请修改主题并在前面加[已解决]

[ 本帖最后由 hanyeguxing 于 2010-5-2 20:36 编辑 ]
1

评分人数

寒夜孤星:在没有说明的情况下,本人所有代码均运行在 XP SP3 下 (有问题请发贴,QQ临时会话已关闭)

TOP

因为我开始没完全说清楚,让各位费解了,实在对不住,在此表示歉意,我已经另行找了一个搜索所有科学计数法的txt,另存到一个文件夹,在用hanyeguxing兄的方法就可以解决了,在这谢谢了,特此结贴。

TOP

有点不明白,楼主一楼的例子,为什么第一行和最后一行的后面都有一个1,但是结果只有最后一行保留了这个1,是根据什么呢?

我也来个,这里你看不到if
  1. @echo off&setlocal enabledelayedexpansion
  2. set file=aaa.txt
  3. for /f "delims=.e tokens=1-4" %%a in (%file%) do (
  4.         for /f "delims=0 tokens=1*" %%x in ("%%c") do (
  5.                 set/a dot=%%y+0
  6.                 set -=0000000000%%a
  7.                 set +=%%b
  8.                 for /f "tokens=1,2" %%1 in ("%%x !dot!") do (
  9.                         set %%1=!%%1:~,%%1%%2!.!%%1:~%%1%%2!
  10.                 )
  11.                 for /f "tokens=*" %%o in ("!-:0= !!+:0= !") do (
  12.                         set str=-%%~nxo.
  13.                         set str=!str:-.=-0.!
  14.                         set str=!str: =0!
  15.                         echo;结果:!str:~1,-1!
  16.                 )
  17.         )
  18. )
  19. pause
复制代码

[ 本帖最后由 netbenton 于 2010-5-2 19:25 编辑 ]

TOP

  哈哈,还是随风18楼的思路简洁,速度更快,可惜楼主一直没有把已知条件交代精确,老是想兼容各种特殊情况,反倒搞复杂了。

  我估计楼主在截取小数点后8位之后,可能还会要求四舍五入、去掉最后的纯0字符串之类的,唉,亲爱的楼主,你这样像挤牙膏一样一次来一点,何时是个尽头啊?
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

似乎楼主没看见23楼的帖子的最后两行,又或是认为那与他无关,只要不是解决我问题的字我坚决不看 ^_^
也怀疑楼主有没有测试18楼的代码。
技术问题请到论坛发帖求助!

TOP

哦,谢谢,是这样的,每个txt内容只有上面贴出的6行,txt文件的数量大概是3千多,
目的是,把全部的txt转换成标准的常规数字
现状是两种txt都有,有些是常规数字,有些是科学计数法,不存在一个txt里面既有常规数字又有科学计数法的情形
思路没变,只不过没表述清楚

[ 本帖最后由 alexwxcong 于 2010-5-2 17:54 编辑 ]

TOP

原帖由 alexwxcong 于 2010-5-2 14:48 发表
不好意思啊,发现一个问题,就是我这种txt文件大概有3千多个,其中差不多1000左右是正常的,没有科学计数的

  到底是某些文本中科学计数和常规计数混杂的,还是每个文档要么全是科学计数要么是常规计数?请说明白一点。

  到目前为止,跟帖已经达到两页,请楼主把所有的需求全部更新到顶楼,否则,别人要准确全面地了解你的本意,还得从头到尾全部看一遍帖子,其间思路一变再变,恐怕没几个人有耐心把你帮到底。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

  用10楼的思路,得到如下代码(仅处理一个文件):
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set str_zero=
  4. for /l %%i in (1,1,10) do set str_zero=0!str_zero!
  5. for /f "tokens=1-3 delims=.e" %%i in (test.txt) do (
  6.     set int=%%i
  7.     set char_int=
  8.     if "!int:~0,1!"=="-" (
  9.         set char_int=-
  10.         set int=!int:~1!
  11.     )
  12.     set dec=%%j
  13.     set e=%%k
  14.     set char_e=!e:~0,1!
  15.     set e=!e:~1!
  16.     call :cut_zero_left !e!
  17.     if "!char_e!"=="+" (
  18.         set str_dec=!dec!%str_zero%
  19.         call set num=!int!%%str_dec:~0,!num_NoLeftZero!%%.%%str_dec:~!num_NoLeftZero!%%
  20.     ) else (
  21.         set str_int=%str_zero%!int!
  22.         call set num=%%str_int:~0,-!num_NoLeftZero!%%.%%str_int:~-!num_NoLeftZero!%%!dec!
  23.     )
  24.     for /f "tokens=1* delims=." %%x in ("!num!") do (
  25.         if "!char_e!"=="-" (
  26.             call :cut_zero_left %%x
  27.             set num_NoRightZero=%%y
  28.         )
  29.         if "!char_e!"=="+" (
  30.             call :cut_zero_right %%y
  31.             set num_NoLeftZero=%%x
  32.         )
  33.     )
  34.     if defined num_NoRightZero (
  35.         echo !char_int!!num_NoLeftZero!.!num_NoRightZero!
  36.     ) else echo !char_int!!num_NoLeftZero!
  37. )
  38. pause
  39. exit
  40. :cut_zero_left
  41. :: 去除字符串最左侧的纯0字符串
  42. set num_NoLeftZero=0
  43. for /f "tokens=1* delims=0" %%i in ("%1") do set num_NoLeftZero=%%i
  44. goto :eof
  45. :cut_zero_right
  46. :: 去除字符串最右侧的纯0字符串
  47. set num_NoRightZero=%1
  48. :loop
  49. if "%num_NoRightZero:~-1%"=="0" (
  50.     set num_NoRightZero=!num_NoRightZero:~0,-1!
  51.     if defined num_NoRightZero goto loop
  52. )
  53. goto :eof
复制代码

  经测试,100行数据耗时约1.5秒,测试环境为:1.6GHZ主频、512M内存、XP_SP3系统。

  若楼主觉得处理结果完全符合你的需要,我将改写代码,以适应成百上千个txt文档的情况;若有其他需求,请继续提出。

  10楼提到的那个问题,是因为没有使用 call 来延迟变量的扩展导致的,和字符串截取长度超过字符串本身长度无关。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

原帖由 随风 于 2010-5-2 13:25 发表
不知道对不对
echo off & setlocal enabledelayedexpansion
for /f "tokens=1,2 delims=e" %%i in (a.txt) do (
   set var=%%j
   for /f "tokens=1,2 delims=." %%a in ("%%i") do (
      set z=%%a&set x ...

我的不是在一个txt里面,是有数千个txt

TOP

原帖由 alexwxcong 于 2010-5-2 11:16 发表
谢谢hanyeguxing ,我先备份一个试过了,按你的方法好像是可以,谢谢啊

不好意思啊,发现一个问题,就是我这种txt文件大概有3千多个,其中差不多1000左右是正常的,没有科学计数的,如果按照hanyeguxing兄这个代码执行,会将其中原本正常的变成这样
0
0
0
0
0.829499998926702
0.3405
原本是这样的
0.2
0
0
-0.2
82949.9998926702
34050

TOP

精度非常接近了
  1. gawk "{printf(\"%.12f\n\",$0)}" a.txt | gawk "{gsub(/0+$/,\"\");gsub(/\.$/,\"\")}1"
复制代码

TOP

不知道对不对
:
  1. @echo off & setlocal enabledelayedexpansion
  2. for /f "tokens=1,2 delims=e" %%i in (a.txt) do (
  3.    set var=%%j
  4.    for /f "tokens=1,2 delims=." %%a in ("%%i") do (
  5.       set z=%%a&set x=%%b00000000000000000
  6.     )
  7.     set f=&set h=
  8.     if "!var:~0,1!"=="-" set f=a
  9.     set var=!var:~1!
  10.     for /f "tokens=* delims=0" %%a in ("!var!") do (
  11.        if "!f!"=="" (set z=!z!!x:~0,%%a!&set x=!x:~%%a!) else (
  12.           if "!z:~0,1!"=="-" set z=!z:-=!&set h=-
  13.           set z=0000000000000000000!z!
  14.           set x=!z:~-%%a!!x!
  15.           set z=!z:~0,-%%a!
  16.           for /f "tokens=* delims=0" %%c in ("!z!") do (
  17.              if "%%c"=="" set z=0
  18.            )
  19.        )
  20.     )
  21.     echo !h!!z!.!x:~0,8!
  22. )
  23. pause
复制代码
技术问题请到论坛发帖求助!

TOP

精度比较低
  1. @echo off
  2. for /f %%a in (a.txt) do (
  3.     math.exe %%a
  4. )
复制代码

TOP

返回列表