标题: [文本处理] [已解决]bat如何查找指定字符串前的数字 [打印本页]
作者: inflikt 时间: 2013-10-22 16:13 标题: [已解决]bat如何查找指定字符串前的数字
现在有若干个txt文件,里面的格式基本一致,如其中一个txt的内容
.....
D 11 Final seasonally adjusted data
From 2003.Jan to 2009.Dec
Observations 84
-----------------------------------------------------------------------------
Jan Feb Mar Apr May Jun
Jul Aug Sep Oct Nov Dec TOTAL
-----------------------------------------------------------------------------
2003 5436.48 5442.45 5459.32 5455.02 5457.04 5455.18
5467.18 5475.61 5466.99 5434.10 5453.44 5460.38 65463.21
2004 5448.64 5445.03 5452.04 5442.37 5441.17 5451.61
5465.41 5473.73 5477.79 5451.15 5458.08 5457.64 65464.66
2005 5540.25 5564.78 5556.51 5294.60 5321.58 5309.99
5338.84 5411.57 5384.81 5471.84 5386.25 5392.34 64973.36
2006 5279.67 5323.10 5288.35 5431.96 5516.74 5551.05
5468.80 5461.49 5581.07 5529.45 5512.74 5438.14 65382.56
2007 5577.12 5421.42 5367.01 5484.88 5606.76 5591.13
5558.89 5551.72 5491.54 5380.13 5523.39 5488.72 66042.72
2008 5365.49 5451.04 5592.67 5544.06 5368.22 5341.43
5066.20 4995.55 5008.65 4517.47 3864.44 4075.86 60191.09
2009 4595.22 5012.21 4990.79 4972.96 5347.19 5460.18
5553.93 5559.29 5323.20 5578.44 5504.65 5613.92 63511.98
AVGE 5320.41 5380.01 5386.67 5375.12 5436.96 5451.51
5417.04 5418.42 5390.58 5337.51 5243.29 5275.29
......
截取是一部分内容,现在希望得到5613.92这个数字,是D 11 Final seasonally adjusted data下面的第一个AVGE(绿色标注),然后之前的第二个数字5613.92,写到另一个txt中
恳求帮助!
作者: DAIC 时间: 2013-10-22 16:57
请把其中一个txt压缩之后传上来看看
作者: inflikt 时间: 2013-10-22 17:02
回复 2# DAIC
附件已添加
作者: foxJL 时间: 2013-10-22 17:07
本帖最后由 foxJL 于 2013-10-22 17:10 编辑
- @echo off&setlocal enabledelayedexpansion
- for /f "tokens=1,6 delims= " %%i in (a.txt) do (
- set/a n+=1,s=n-1
- set str!n!=%%j
- if /i %%i equ avge call echo %%str!s!%%
- )
- pause
复制代码
作者: inflikt 时间: 2013-10-22 17:15
回复 4# foxJL
多谢foxJL大大,不过测试下来有很多多余的数据
作者: foxJL 时间: 2013-10-22 17:18
回复 5# inflikt
一个文本里是不是有很多个AVGE?
我直接用你上面发出来的文本测试的,没有问题.
作者: inflikt 时间: 2013-10-22 17:20
回复 6# foxJL
是的,有很多AVGE,我后面上传附件了,我只是需要D 11 Final seasonally adjusted data之后AVGE之前的那个数据
作者: apang 时间: 2013-10-22 19:19
- @echo off&setlocal enabledelayedexpansion
- for /f "tokens=*" %%a in (a.txt) do (
- if defined flag (
- for /f "tokens=1,6" %%b in ("%%a") do (
- if /i "%%b"=="AVGE" set "flag=" & echo,!Num!
- set "Num=%%c"
- )
- )
- if /i "%%a"=="D 11 Final seasonally adjusted data" set flag=1
- )
- pause
复制代码
作者: inflikt 时间: 2013-10-22 21:27
回复 8# apang
apang大大,我测试了下,得出的结果是5347.19,是2009之后是第五个数,不是需要的那个数。
作者: apang 时间: 2013-10-22 21:59
回复 9# inflikt
我用附件测试没有问题,5613.92
作者: inflikt 时间: 2013-10-22 22:06
回复 inflikt
我用附件测试没有问题,5613.92
apang 发表于 2013-10-22 21:59
嗯,谢谢apang大大,我用附件测试了下也没有问题,不过还有很多txt文件是D11 Final seasonally adjusted data,D跟11之间没有空格,所以导致错误。。
所以大大能给完善下,D11或者是D 11就不要判断了。而且有很多txt文件要同样的方法去查找,能不能做一个查找本目录下所有txt文件中的指定数字,然后导出到一个保存结果的txt文件中呢。
作者: foxJL 时间: 2013-10-22 22:16
根据apang的思路来一个支持多TXT文本的
- @echo off&setlocal enabledelayedexpansion
- for /f "delims=" %%a in ('dir /a-d /b /s *.txt') do (
- for /f "tokens=1,5,6 delims= " %%i in (%%a) do (
- if defined flag (
- if /i %%i equ avge set "flag=" & echo "%%~nxa" --- !str!
- set str=%%k
- )
- if /i "%%j %%k"=="adjusted data" set flag=1
- )
- )
- pause
复制代码
作者: inflikt 时间: 2013-10-22 23:36
回复 12# foxJL
foxJL 大大,我测试过了,有2个问题,一个是部分文件写的是D 11 Final seasonally adjusted data,部分文件是D11 Final seasonally adjusted data(是因为这些txt文件都是另一个软件的导出结果,所以存在差异),您的代码"tokens=1,5,6只能是解决D 11 Final seasonally adjusted data,能不能把两种情况都考虑进去。
还有一个问题是,数据不对,AVGE前面的是2009年的13个数据,12个是对应月份,另一个是平均值,但是不一定有13个数据,有可能月份不足,现在需要的是AVGE前面倒数第二个数,实际就是2009年的最后一个数。您的代码执行结果是5347.19,是第五个月的数据不符合需求。
求大大指点。。
另我上传了另一个txt文件,望大大测试可行性。
作者: apang 时间: 2013-10-22 23:54
本帖最后由 apang 于 2013-10-23 09:16 编辑
这样试试呢?- @echo off&setlocal enabledelayedexpansion
- (for %%i in (*.txt) do (
- set "Num=" & set "flag="
- for /f "usebackq tokens=1*" %%a in ("%%i") do (
- set "str=%%a %%b"
- if defined flag (
- if /i "%%a"=="AVGE" set "flag=" & echo,!Num!
- for %%c in (!str!) do set "Num=!a!" & set "a=%%c"
- )
- if /i "!str: =!"=="D11Finalseasonallyadjusteddata" set flag=1
- )
- ))>$
- move $ Result.txt
- pause
复制代码
作者: inflikt 时间: 2013-10-23 00:08
回复 14# apang
apang大大辛苦了,不过我测试下来还是数据错误(还是5347.19),是不是因为要的数跟AVGE不在同一行的缘故。抱歉新手了,看代码吃力
作者: inflikt 时间: 2013-10-23 00:25
回复 14# apang
apang大大,您的代码执行过后我发现一个问题,我的其中一个txt文件代码部分截取如下
D11 Final seasonally adjusted data
From 2005.Jan to 2010.Feb
Observations 62
-----------------------------------------------------------------------------------------------------------------------------------
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec TOTAL
-----------------------------------------------------------------------------------------------------------------------------------
2005 5560.87 5591.96 5599.21 5314.09 5283.27 5257.40 5341.94 5424.71 5403.71 5445.10 5362.25 5384.08 64968.60
2006 5299.67 5358.86 5340.71 5449.64 5472.21 5491.96 5469.75 5474.28 5603.07 5505.59 5487.61 5427.77 65381.14
2007 5591.09 5465.43 5419.30 5502.66 5562.31 5531.94 5559.30 5563.93 5513.07 5355.59 5497.61 5477.77 66040.00
2008 5381.09 5495.43 5649.30 5562.66 5322.31 5281.94 5069.30 5003.93 5023.07 4495.59 3837.61 4067.77 60190.00
2009 4611.09 5055.43 5049.30 4992.66 5302.31 5401.94 5559.63 5564.00 5332.27 5554.77 5477.28 5608.04 63508.72
2010 5653.99 5370.36 11024.35
AVGE 5349.63 5389.58 5411.56 5364.34 5388.48 5393.04 5399.99 5406.17 5375.04 5271.33 5132.47 5193.09
应该是要得到5370.36(D11下面第一个AVGE,AVGE前面的第二个数),而实际运行结果是5302.31
作者: apang 时间: 2013-10-23 00:32
蛋疼,试试vbs先,明天再说- Set fso = CreateObject("Scripting.FileSystemObject")
- strKey ="D *11 Final seasonally adjusted data"
-
- For Each file in fso.GetFolder(".").Files
- If LCase(Right(file.Name,4)) = ".txt" Then
- RegEx fso.OpenTextFile(file).ReadAll
- End If
- Next
-
- Sub RegEx(text)
- Set re = New RegExp
- re.Pattern = strKey & "[\s\S]+?([^ ]+) +[^ ]+\s+AVGE"
- re.IgnoreCase = True
- For Each a In re.Execute(text)
- fso.OpenTextFile("Result.txt",8,True).WriteLine a.SubMatches(0)
- Next
- End Sub
复制代码
作者: tmplinshi 时间: 2013-10-23 00:45
本帖最后由 tmplinshi 于 2013-10-23 02:04 编辑
- sed -n -r "/Final seasonally adjusted data/I,/AVGE/I! d; // {x; s/.* ([0-9.]+) +[0-9].*/\1/p}; /\./ h" *.txt
复制代码
如果没有 sed,请点击我签名里的链接下载。
作者: foxJL 时间: 2013-10-23 00:47
本帖最后由 foxJL 于 2013-10-23 10:21 编辑
情况太复杂,写着写着就成这样了.我在本地测试能过,希望不会再出现别的情况- @echo off&setlocal enabledelayedexpansion
- for /f "delims=" %%a in ('dir /a-d /b /s *.txt') do (
- for /f "usebackq tokens=1,* delims= " %%i in ("%%a") do (
- set "n="
- if defined flag (
- if /i "%%i"=="avge" (
- set "flag="
- for %%A in (!str1!) do (
- set/a n+=1,s=n-1
- set str_!n!=%%A
- )
- call echo "%%~nxa" --- %%str_!s!%%
- )
- set str1=%%j
- )
- set str=%%i%%j
- set str=!str: =!
- if /i "!str!"=="D11Finalseasonallyadjusteddata" set flag=1
- )
- )
- pause
复制代码
作者: apang 时间: 2013-10-23 09:20
回复 16# inflikt
14#改一下,试试看
作者: foxJL 时间: 2013-10-23 09:27
19楼更新了一下,应该可以了吧
作者: inflikt 时间: 2013-10-23 10:03
回复 20# apang
apang大大,改动后测试成功,能得出正确结果,现正在学习代码中,谢谢!
作者: inflikt 时间: 2013-10-23 10:08
回复 21# foxJL
foxJL大大,辛苦了,您的代码我测试过,还是那个问题,如果AVGE上一行数据不够的话得不出结果,详见16#代码或是13#的附件
作者: inflikt 时间: 2013-10-23 10:11
回复 18# tmplinshi
tmplinshi 大大,您的代码我测试下来跟foxJL的问题一样,就是16#代码执行不出结果,另大大辛苦了,夜里2点多还在帮我修改。
作者: foxJL 时间: 2013-10-23 10:23
回复 23# inflikt
再测试一下19楼的代码,在我本地是没有问题的.
因为公司电脑禁用了下载所以无法下载你的附件测试,只能用你16L的文本测试的.
作者: tmplinshi 时间: 2013-10-23 17:05
本帖最后由 tmplinshi 于 2013-10-23 17:40 编辑
sed 代码我测试没问题的,你是不是修改了代码?如果要加上 D11 的话,这样改:- sed -n -r "/D\s*11\s*Final seasonally adjusted data/I,/AVGE/I! d; // {x; s/.* ([0-9.]+) +[0-9].*/\1/p}; /\./ h" *.txt
复制代码
如果结果不正确的话,最好把那个文本以附件形式上传上来。
作者: terse 时间: 2013-10-23 22:35
本帖最后由 terse 于 2013-10-24 15:20 编辑
- @echo off&setlocal enabledelayedexpansion
- for /f "tokens=*" %%i in ('dir /b/a-d *.txt') do (
- set "flag="
- for /f "usebackqtokens=1*" %%a in ("%%i") do (
- if defined flag (
- if /i "%%a" == "AVGE" (
- for /f "tokens=*" %%c in ("!var: =\!\!str: =\!\..") do echo %%~nxc
- set "flag="
- ) else set "var=!str!"
- ) else if /i "!str: =!" == "D11Finalseasonallyadjusteddata" set flag=1
- set "str=%%a%%b"
- )
- )
- pause
复制代码
作者: inflikt 时间: 2013-10-24 11:16
回复 26# tmplinshi
似乎还是这个问题,我现在打包上来3个文件,只能得到2个数字,不知道是不是我这边的问题
作者: inflikt 时间: 2013-10-24 11:19
回复 27# terse
好像得出的结果很奇怪,我这边测试的3个文件,应该是得出3个数字,结果却是2个数字和一个中文。。。详见28楼附件
作者: foxJL 时间: 2013-10-24 12:21
回复 28# inflikt
终于知道是什么问题了,b.txt 2009的下面一行才一个数字...重新修改了一下,应该可以了.- @echo off&setlocal enabledelayedexpansion
- for /f "delims=" %%a in ('dir /a-d /b /s *.txt') do (
- set "n="
- for /f "usebackq tokens=1,* delims= " %%i in ("%%a") do (
- if defined flag (
- for %%A in (!str!) do (set/a n+=1,s=n-1 & set str_!n!=%%A)
- if /i "%%i"=="avge" (set "flag=" & call echo "%%~nxa" --- %%str_!s!%%)
- )
- set str=%%i %%j
- if /i "!str: =!"=="D11Finalseasonallyadjusteddata" set flag=1
- )
- )
- pause
复制代码
作者: inflikt 时间: 2013-10-24 13:29
回复 30# foxJL
多谢foxJL ,测试可用。
作者: terse 时间: 2013-10-24 15:20
回复 29# inflikt
AVGE 上面目标行只存在一列的时候不够了, 只能再从上面借一行了 修正下试
作者: tmplinshi 时间: 2013-10-24 22:48
本帖最后由 tmplinshi 于 2013-10-24 23:05 编辑
回复 tmplinshi
似乎还是这个问题,我现在打包上来3个文件,只能得到2个数字,不知道是不是我这边的问 ...
inflikt 发表于 2013-10-24 11:16
- sed -n -r "/D\s*11\s*Final seasonally adjusted data/I,/AVGE/I! d; // {x; s/^.* ([0-9.]+)\s+[0-9.]+.*$/\1/p; x; d}; /\./ H" *.txt
复制代码
谢谢楼主,通过你这个问题我对 sed 又更了解了一点。
作者: inflikt 时间: 2013-10-25 08:53
回复 33# tmplinshi
tmplinshi 大大,测试可用,另大大辛苦了,sed很强大,正在努力学习 !
作者: terse 时间: 2013-10-25 18:07
回复 33# tmplinshi
这样是否省点空间呢- sed -nr "/D\s*11\s*Final seasonally adjusted data/I,/AVGE/I{/AVGE/I{x;s/^.* ([0-9.]+)\s+[0-9.]+.*$/\1/p;d;x};H}" *.txt
复制代码
作者: tmplinshi 时间: 2013-10-26 00:54
回复 tmplinshi
这样是否省点空间呢
terse 发表于 2013-10-25 18:07
谢谢,这样是好一点。
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |