Board logo

标题: [数值计算] [已解决]把txt文本中的数字全部乘一个倍数后取整,替换掉原数字? [打印本页]

作者: vicodin    时间: 2024-11-27 21:40     标题: [已解决]把txt文本中的数字全部乘一个倍数后取整,替换掉原数字?

本帖最后由 vicodin 于 2024-11-28 20:08 编辑

大家好。我的abc.txt文件中有汉字、英文及数字,如何在这个txt中查找到所有的数字(均为整数),给数字乘以0.925,然后取整(直接把小数部分去掉,不用四舍五入),替换掉原来的数字?

abc.txt内容的一部分:
指标a数值为180,指标b则是:80

这段文本经处理后应变成:
指标a数值为166,指标b则是:74

感谢感谢
作者: aloha20200628    时间: 2024-11-27 22:56

本帖最后由 aloha20200628 于 2024-12-2 19:20 编辑

回复 1# vicodin

批处的浮点运算选用 powershell 代劳,顺便再给代劳 ‘整数提取及其排序’,以免后续整体替换时遭遇 ‘大小数嵌套重复’ 的陷阱(避免 ‘...180...80...’ 或 ‘...80...180...’ 文本行有 "大小数嵌套重复" 时被整体替换可能导致的错误)... 以下代码存为 test.bat 运行,与源文件 abc.txt 同目录
  1. @echo off & (for /f "delims=" %%a in (abc.txt) do (
  2.    set "s=%%a" &for /f %%x in (
  3.       'powershell "$a='%%a' -replace '\D+(\d+)',',$1,';$a.split(',')|sort{[int]$_} -des" '
  4.    ) do (setlocal enabledelayedexpansion &for /f %%n in (
  5.       'powershell "[int](%%x*0.925)" ') do set "s=!s:%%x=%%n!")
  6.    echo,!s!&endlocal))>abc.new.txt
  7. pause&exit/b
复制代码

作者: wanghan519    时间: 7 天前 09:05

本帖最后由 wanghan519 于 2024-11-28 09:20 编辑
  1. cat a.txt | perl -pe 's/\d+/int($& * 0.925)/ge'
复制代码
想来想去perl正则最好用,不知道其他工具有没有类似的,可以在正则替换里执行运算的。。。


不查不知道,原来python、js、go、php、c#都支持类似的用法。。。汗。。。
作者: Five66    时间: 7 天前 12:24

来个ruby的 ,虽然执行效率慢点 ,但是代码写起来是真的爽爽
  1. ruby -Egbk -n -e "puts $_.gsub(/\d+/){|x| (x.to_i*0.925).to_i}" abc.txt >new_abc.txt
复制代码

作者: aloha20200628    时间: 7 天前 13:09

本帖最后由 aloha20200628 于 2024-12-2 19:19 编辑

回复 1# vicodin

批处调用 powershell 速度较慢,再给一个能明显提速的版本(存为 test.bat 运行,与源文件 abc.txt 同目录),须在本坛第三方下载以下工具(落地即用,与批处脚本同目录,其中 sort 须更名为 sort76.exe)
   grep v311 http://bcn.bathome.net/s/tool/index.html?key=grep
   gawk v413 http://bcn.bathome.net/s/tool/index.html?key=gawk
   sort v76 http://bcn.bathome.net/s/tool/index.html?key=sort
避免 ‘...180...80...’ 或 ‘...80...180...’ 文本行有 "大小数嵌套重复" 时被整体替换可能导致的错误
  1. @echo off & (for /f "delims=" %%a in (abc.txt) do (
  2.    set "s=%%a" &for /f %%x in ('echo,"%%a"^|grep -o -E "[0-9]+"^|sort76 -n -r') do (
  3.    setlocal enabledelayedexpansion &for /f %%n in (
  4.    'gawk "BEGIN{print(int(%%x*0.925))}" ') do set "s=!s:%%x=%%n!")
  5.    echo,!s!&endlocal))>abc.new.txt
  6. pause&exit/b
复制代码

作者: aloha20200628    时间: 7 天前 18:25

本帖最后由 aloha20200628 于 2024-12-2 19:18 编辑

回复 1# vicodin

若不想预先下载 GNU 系列工具,可用以下 bat+jscript 版本(存为 test.bat 运行,与源文件 abc.txt 同目录),也会比2楼 bat+powershell 版本明显提速...
避免 ‘...180...80...’ 或 ‘...80...180...’ 文本行有 "大小数嵌套重复" 时被整体替换可能导致的错误
  1. 2>1/* ::
  2. @echo off & type "abc.txt"|cscript /nologo /e:jscript "%~f0">"abc.new.txt"
  3. pause&exit/b */
  4. ws=WSH.stdin;
  5. while (!ws.atendofstream) {
  6.    s=ws.readline(), a=s.match(/\d+/g), a=a.sort(function(a,b){return b-a});
  7.    for (i=0,l=a.length; i<l; i++) {
  8.       sn=Math.floor(a[i]*0.925), eval('r=/'+a[i]+'/gi;'), s=s.replace(r,sn); }
  9.    WSH.echo(s); }
复制代码

作者: vicodin    时间: 7 天前 20:09

回复 6# aloha20200628

好的,感谢你的帮助。明天给你评分,今天评分已经用完了。
作者: WHY    时间: 4 天前 22:17

  1. PowerShell "$s = (gc a.txt -ReadCount 0) -join \"`r`n\"; $s=[regex]::Replace($s, '[0-9]+', {[Math]::Floor(0.925*$args[0].Value)}); sc b.txt $s"
复制代码

作者: WHY    时间: 4 天前 22:35

  1. @if(0)==(0) echo off
  2. type a.txt | cscript //nologo //e:jscript "%~f0" > b.txt
  3. pause & exit/b
  4. @end
  5. var s = WSH.StdIn.ReadAll();
  6. s = s.replace(
  7.     /[0-9]+/g,
  8.     function(s0){return Math.floor(0.925*s0);}
  9. )
  10. WSH.Echo(s);
复制代码

作者: Five66    时间: 4 天前 23:33

再来个python的 ,需要python版本3.8以上
不得不说 ,python这种强制缩进的语言弄成一行流真的蛋疼
  1. python -c "(r:=__import__('re')) and (s:=__import__('sys')) and (list(map(lambda x:print(r.sub('\\d+',lambda y:str(int(int(y.group())*0.925)),x),end=''),open(s.argv[1],'r',-1,'gbk'))))" abc.txt >new_abc.txt
复制代码

作者: aloha20200628    时间: 3 天前 18:55

本帖最后由 aloha20200628 于 2024-12-2 19:19 编辑


另一版 bat+Python 混编脚本,存为 test.bat 运行,与源文件 abc.txt 同目录...
避免 ‘...180...80...’ 或 ‘...80...180...’ 文本行有 "大小数嵌套重复" 时被整体替换可能导致的错误
  1. @echo off &more +1 "%~f0">"_._"&python "_._">"abc.new.txt"&del/q "_._"&exit/b
  2. import re
  3. with open('abc.txt') as f:
  4. for l in f:
  5. for d in re.findall('\d+',l):
  6. l=l.replace(d, f'{int(int(d)*0.925)}', 1)
  7. print(l, end='')
复制代码





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