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

[文本处理] 批处理如何对文本里各列数据分别除以指定数值

本帖最后由 meiszp 于 2016-9-29 11:18 编辑

文件夹下有许多数据文件(扩展名为txt或指定),文件内容为多列数据(下面为7列,但实际可能更多),想对每列除以一个数,比如第1列除以10,第2列除以20等等。
求大侠赐教。

-6.70552254e-007  4.56646750e+005  6.89739219e+004 -3.81691500e+005  2.08684141e+005 -4.90864719e+005  3.10406906e+005
  5.00000007e-002  4.61931250e+005  1.36446094e+005 -3.59222750e+005  2.07390922e+005 -4.75073250e+005  3.40052250e+005
  9.99993235e-002  4.98387563e+005  2.60942938e+005 -3.52485344e+005  2.02917281e+005 -4.60640719e+005  3.66940344e+005
  1.50000006e-001  5.08161344e+005  3.97039625e+005 -3.58057656e+005  1.97205422e+005 -4.43923438e+005  3.92823375e+005
  1.99999332e-001  4.81562063e+005  5.06175219e+005 -3.86291063e+005  1.91434969e+005 -4.22848281e+005  4.17620406e+005
  2.50000000e-001  4.46009031e+005  5.63322500e+005 -4.38631031e+005  1.88274859e+005 -3.97913656e+005  4.41026063e+005
  2.99999326e-001  4.34343250e+005  5.40127375e+005 -4.90687344e+005  1.88438328e+005 -3.70999531e+005  4.62318875e+005
  3.49999994e-001  4.58196469e+005  4.70192063e+005 -5.18217250e+005  1.90427172e+005 -3.43401031e+005  4.79834125e+005
  3.99999321e-001  4.85120313e+005  3.84186875e+005 -5.56579813e+005  1.93310938e+005 -3.15954906e+005  4.95534531e+005


数据文件见网盘 http://share.weiyun.com/6bdcb931f8703b3830a9c9d711f5e053

发现win8.1(PowerShell 4.0)与 win7(PowerShell 2.0)在脚本块中定义变量有区别
脚本块中的变量作用域原本应该是Local性质的,但win7把它当作Global传递,混乱了。

以下代码win7、win8.1测试通过(第1列/10;第2列/20;第3列/30;......):
  1. @echo off
  2. set "r='\d+\.?\d*[Ee][-+]\d{3}'"
  3. set "s=[IO.File]::ReadAllText($_,[Text.Encoding]::Default)"
  4. md new\ 2>nul
  5. PowerShell -c "dir *.txt|%%{[regex]::Replace(%s%,\"[^^`r`n]+\",{param($a,$global:i=0);[regex]::Replace($a.Value,%r%,{param($b);($b.Value/++$global:i/10).ToString('e8')})})>('new\'+$_.Name)}"
  6. pause
复制代码

TOP

python 的pandas 处理起来真的是完全不费力啊。

pandas 是一个python用来进行数据处理和计算的库,提供了很多非常简单友好易用的数据处理相关的接口.

处理单个文件的代码示例:
  1. #2016年9月30日 08:39:27 codegay
  2. from pandas import *
  3. csv = read_csv("F31_03.txt",sep='\s+',header=None)
  4. s = Series([10,20,30,40,50,60,70])
  5. newcsv = csv / s #csv 中的数据每列除以 s中对应的数值
  6. print(newcsv)
复制代码
去学去写去用才有进步。安装python3代码存为xx.py 双击运行或右键用IDLE打开按F5运行

TOP

本帖最后由 pcl_test 于 2016-9-29 23:39 编辑

回复 31# meiszp
26楼
  1. powershell -c "dir *.txt|?{$_ -is [IO.FileInfo]}|%%{gc $_|%%{if($_ -match '^\s*$'){$_}else{$a=($_.trim() -split '\s+');$line='';for($i=0;$i -le ($a.length-1);$i++){$line+='  '+('{0:e8}' -f ($a[$i]/指定的共同除数))};$line.trim()}}|out-file ('New_'+$_.name) -encoding ascii}"
  2. pause
复制代码
28楼($b.Value/++$i)改为($b.Value/指定的共同除数)

TOP

回复 28# WHY

谢谢!您的代码似乎也对文件数据做了修改,但看不懂,如果想更改除数,不知道怎么做。

TOP

回复 26# pcl_test

多谢大神,数据已经上传了,前面是有空格的,但21楼和26楼代码完美解决,26楼的更简洁。
还想好奇的问问,如果每列除的数相同,是不是还可以简单些?

TOP

本帖最后由 523066680 于 2016-9-29 10:41 编辑
回复  523066680

谢谢,小白还是喜欢纯批,不用安装其他东西。
meiszp 发表于 2016-9-28 22:22



    哈哈哈,这句话说的好任性,潜台词是:
小白还是喜欢各位大大用纯批处理帮我服务,不要安装其他东西,that's too easy,you guys must pay more time.
1

评分人数

TOP

回复 27# /zhqsystem/zhq


   科学计数法
去学去写去用才有进步。安装python3代码存为xx.py 双击运行或右键用IDLE打开按F5运行

TOP

这个帖子真的特么火了吗?
  1. @echo off
  2. set "r='\d+\.?\d*[Ee][-+]\d{3}'"
  3. md new\ 2>nul
  4. PowerShell -c "dir *.txt|%%{$str=[IO.File]::ReadAllText($_,[Text.Encoding]::Default);[regex]::Replace($str,\"[^^`r`n]+\",{param($a);$i=0;[regex]::Replace($a.Value,%r%,{param($b);($b.Value/++$i).ToString('e8')})})>('new\'+$_.Name)}"
  5. pause
复制代码

TOP

也许有错误,错误在计算方法上也许错误文化有限看不懂这个数值
一般可以看得懂代码和移位类似,支持超过for变量占用超出分列,但是不能超过最大变量字符数
只看方法吧
  1. @echo off&&setlocal enabledelayedexpansion
  2. set "[set]=10 20 30 40 50 60 80"
  3. for /l %%n in (1,1,8192)do (
  4. for /f "tokens=1,* delims= " %%i in ("![set]!")do (
  5.   set "[set]=%%j"&&set/a "[set][n]+=1"
  6.   for /f "delims=" %%n in ("![set][n]!")do set "[set][new][%%n]=%%i"
  7. )
  8. )
  9. for /f "delims=" %%i in ('type "新建文本文档 (4).txt"')do (
  10. set "[type]=%%i"&&set "[type][n]="&&set "[true]="
  11. for /l %%n in (1,1,![set][n]!)do (
  12.   for /f "tokens=1,* delims= " %%i in ("![type]!")do (
  13.    set "[type]=%%j"&&set/a "[type][n]+=1"
  14.    for /f "delims=" %%n in ("![type][n]!")do (
  15.     set "[calc]=%%i/![set][new][%%n]!"
  16.     call :[calc]
  17.     if defined [true] (
  18.      set "[true]=![true]! ![calc][new]!"
  19.     )else (
  20.      set "[true]=![calc][new]!"
  21.     )
  22.    )
  23.   )
  24. )
  25. echo/
  26. echo,![true]!
  27. )
  28. pause
  29. exit
  30. :[calc]
  31. for /f "delims=" %%c in ('mshta.exe "vbscript:createobject("scripting.filesystemobject").getstandardstream(1).write(%[calc]%)(close)"') do set "[calc][new]=%%~c"
  32. goto:eof
复制代码
这么好的论坛你上哪找,运行测试环境为6.1.7601-64
注:请遵守互联网信息安全,勿用于非法用途

TOP

本帖最后由 pcl_test 于 2018-4-12 15:10 编辑

$map=@{'0'=10;'1'=20;'2'=30;'3'=40;'4'=50;'5'=60;'6'=70;'7'=80;'8'=90;'9'=100;'10'=110;'11'=120;……}
此处定义每列的除数,如'0'=10表示第1列除以10,'1'=20表示第2列除以20……以此类推,只要定义到最大的列即可,如最多有20列,则定义到'19'=除数,如果不对某列操作,则该列不需定义除数或定义除数为1
  1. powershell -c "$map=@{'0'=10;'1'=20;'2'=30;'3'=40;'4'=50;'5'=60;'6'=70;'7'=80;'8'=90;'9'=100;'10'=110;'11'=120};dir *.txt|?{$_ -is [IO.FileInfo]}|%%{gc $_|%%{if($_ -match '^\s*$'){$_}else{$a=($_.trim() -split '\s+');$line='';for($i=0;$i -le ($a.length-1);$i++){if($map.ContainsKey(''+$i)){$line+='  '+('{0:e8}' -f ($a[$i]/$map[''+$i]))}else{$line+=' '+$a[$i]}};$line.trim()}}|out-file ('New_'+$_.name) -encoding default}"
  2. pause
复制代码

TOP

回复 23# WHY

谢谢!在D:\Test\a.txt下试用了下,没什么改变,没有对每列除以一个数。

TOP

回复 21# pcl_test
谢谢!如果不是7列的话,应该是更改下面红色部分了。我试验了下没问题,非常感谢。
powershell -c "dir  *.txt|?{$_ -is [IO.FileInfo]}|%%{gc $_|%%{$a=($_.Trim() -split '\s+');'{0:e8} {1:e8} {2:e8} {3:e8} {4:e8} {5:e8} {6:e8}' -f ($a[0]/10),($a[1]/20),($a[2]/30),($a[3]/40),($a[4]/50),($a[5]/60),($a[6]/70)}|out-file ('New_'+$_.name) -encoding ascii}"
pause

TOP

PowerShell
  1. $str = [IO.File]::ReadAllText('D:\Test\a.txt', [Text.Encoding]::Default);
  2. [regex]::Replace($str, "[^`r`n]+", {param($a); $i=0; [regex]::Replace($a.Value, '\S+', {param($b); ($b.Value/++$i).ToString('e8')})})
复制代码

TOP

回复 20# happy886rr

每列除的数可以先代替,用时自己修改。比如有20列,1列/1、2列/2、3列/3……20列/20。
如果有10列,是不是把代码里的20,也可能是个控制代码,修改到10,后面相应的1列/1、2列/2、3列/3……10列/10。

TOP

返回列表