标题: [文本处理] 【已解决】批处理:提取各列特定位置的数值 [打印本页]
作者: 思想之翼 时间: 2013-3-1 09:56 标题: 【已解决】批处理:提取各列特定位置的数值
附件中,第一列是时序,第二列--第N列记录数值。
欲根据第二列-第N列的条件,提取特定位置的数值。
以第三列为例:
1、时序0000001的数值是12,该时序向下第一次再次出现数值12的是时序为0000009行,则取时序0000008行的数值11,写入新建的txt文本;
2、时序0000002的数值是08,该时序向下第一次再次出现数值08的是时序为0000017行,则取时序0000016行的数值12,写入新建的txt文本;
3、时序0000003的数值是11,该时序向下第一次再次出现数值11的是时序为0000006行,则取时序0000005行的数值13,写入新建的txt文本;
4、时序0000003、0000004、0000005......如此逐行向下位移,根据第一次再次出现相同数值的所在行,提取其前一行的数值,写入新建的txt文本;
5、若时序0000099的数值是16,该时序向下没有再次出现数值16,则在新建的txt文本中记为空格。
第四列-第N列同理提取特定位置的数值,写入新建的txt文本。新建txt文本的数据格式,如同去除时序的附件文本。
不知道说明白没有。恳望得到大师的帮助!
作者: wankoilz 时间: 2013-3-2 14:11
提取出来的这么多数值在保存的时候按照什么格式,和附件的数据格式一样吗,
比如你说的0000001的数值是12,查询后提取到11,这个11直接替换原来12的位置呢还是怎么说?
作者: apang 时间: 2013-3-2 17:57
本帖最后由 apang 于 2013-3-4 11:07 编辑
- Set FSO = CreateObject("Scripting.FileSystemObject")
- Set File = FSO.OpenTextFile("a.txt")
- T = Time
- Do Until File.atEndOfStream
- Text = File.ReadLine
- If RegEx <> "" Then '排除空行
- A = Split(RegEx," ")
- m = UBound(A) 'm=列数
- ReDim PreServe B(m,n) '申明数组B
- For i = 0 to m :B(i,n) = A(i) :Next '数组B赋值
- n = n + 1 '行数
- End If
- Loop
-
- n = n - 1
- For i = 1 to m 'm=列数
- For j = 0 to n 'n=行数
- flag = 1
- For k = j + 1 to n
- If B(i,j) = B(i,k) Then '相等则赋值为上一行的值
- flag = 0 :B(i,j) = B(i,k-1) :Exit For
- End If
- Next
- If flag Then B(i,j) = " " '不相等则赋值为空格
- Next
- Next
-
- For i = 0 to n '写入文件
- Str = ""
- For j = 1 to m : Str = Str & vbTab & B(j,i) : Next
- FSO.OpenTextFile("b.txt",8,true).WriteLine B(0,i) & Str
- Next
- MsgBox T & vbLf & Time
-
- Function RegEx()
- Set Re = New RegExp
- Re.Pattern = "\s+"
- Re.Global = True
- RegEx = Trim(Re.Replace(Text," "))
- End Function
复制代码
保存为test.vbs,不知道能否满足要求,试一下
作者: terse 时间: 2013-3-3 00:55
P来下- @echo off&setlocal enabledelayedexpansion
- for /f "tokens=1*" %%i in (a.txt) do (
- set /a num+=1,n=0
- set _!num!=%%i
- for %%a in (%%j) do (
- set /a n+=1
- for %%b in (!n!) do set $%%b=!$%%b! %%a
- )
- )
- for /l %%i in (1 1 %n%) do (
- for /l %%j in (1 1 %num%) do (
- for /f "tokens=1*" %%a in ("!$%%i!") do (
- set s=&set f=%%a&set "$%%i=%%b"
- for %%c in (%%b) do (
- if not defined s (
- if %%a equ %%c set s=!f!
- set f=%%c
- )
- )
- )
- set #%%j=!#%%j! !s!
- )
- )
-
- (for /l %%i in (1 1 !num!) do echo !_%%i!!#%%i!)>a2.txt
-
- pause
复制代码
作者: 思想之翼 时间: 2013-3-3 18:11
回复 3# apang
您的代码,运算正确,速度迅速,赞一下!也羡慕一把,要是我自己也会写,多好!
这个代码,解决的是一列数值中,首位一个数值与下相同,则取第一个与之相同数值的前一个数,如果扩展一下,首两个数值与下两个数值相同,则取第一个与之相同的前一个数值,即如:
8
5
6
3
2
1
8
5
首两个数值是8 5,该列第一个与8 5这两个数相同的前一个数值是1,则取之。
如若这样,代码该修改何处?
我明白了这点,首三个数值、首四个数值......等,自己就可以扩展运用了。
盼望大师指点!
作者: apang 时间: 2013-3-3 20:03
回复 5# 思想之翼
两行同时比较,可以将中间那段循环改成下面的:- For i = 1 to m '总列数
- For j = 0 to n '总行数
- f = 1
- For k = j + 1 to n
- If j + 1 <= n and k + 1 <= n Then
- If b(i,j) = b(i,k) and b(i,j+1) = b(i,k+1) Then '有重复则赋值为上一行的值
- f = 0 :b(i,j) = b(i,k-1) :Exit For
- End If
- End If
- Next
- If f Then b(i,j) = " " '没有重复则赋值为空格
- Next
- Next
复制代码
作者: 思想之翼 时间: 2013-3-4 01:19
回复 3# apang
附件中的样本运行该代码时出错,运行代码得到的b.txt,和a.txt的数值一样,代码没有运行。是a.txt中有空格空行,还是数值间距的问题?烦请大师帮助查看一下,好吗?
出错样本中附保存为test.vbs的代码、a.txt文本。
作者: apang 时间: 2013-3-4 11:09
回复 7# 思想之翼
好吧,3#修改了,试下
作者: 思想之翼 时间: 2013-3-7 20:04
本帖最后由 思想之翼 于 2013-3-7 20:50 编辑
回复 8# apang
终于弄明白为什么出错了,所有的根源在于:通过下述代码得到的文本,数值间的空格格式是Tab,和批处理前的原文本空格格式(键盘空格键的格式)不同。用下述代码得出的数值,在后续的sheet1、sheet2对应单元格单元格比较对错、1个单元格为空或2个单元格都为空时,不参与比较,这时就出错了,即空格参与了比较。故此,诚恳地询问老师:下述代码能否略做改动,使其得到的文本,数值间的空格格式为键盘空格的格式? 如果不是Tab就不能反映几个连续空格的情况,那么,后续2个sheet单元格比较对错、空格不参与比较时,又该如何处理?
Set FSO = CreateObject("Scripting.FileSystemObject")
Set File = FSO.OpenTextFile("a.txt")
Do Until File.atEndOfStream
Text = File.ReadLine
If Text <> "" Then '排除空行
a = Split(RegEx," ")
m = UBound(a) '总列数
ReDim PreServe b(m,n) '定义数组
For i = 0 to m :b(i,n) = a(i) :Next '数组赋值
n = n + 1 '行数
End If
Loop
n = n - 1
For i = 1 to m '总列数
For j = 0 to n '总行数
f = 1
For k = j + 1 to n
If b(i,j) = b(i,k) Then '有重复赋值为上一行的值
f=0 :b(i,j)= b(i,k-1) :Exit For
End If
Next
If f Then b(i,j) = " " '没有重复则赋值为空格
Next
Next
For i = 0 to n '写入文件
Str = ""
For j = 1 to m : Str = Str & vbTab & b(j,i) : Next
FSO.OpenTextFile("b.txt",8,true).WriteLine b(0,i) & Str
Next
MsgBox "OK"
Function RegEx() '多个连续空格替换成一个空格
Set Re = New RegExp
Re.Pattern = " +"
Re.Global = True
RegEx = Re.Replace(Text," ")
End function
作者: apang 时间: 2013-3-7 21:58
回复 9# 思想之翼
vbTab换成chr(32)
作者: 思想之翼 时间: 2013-3-10 16:30
本帖最后由 思想之翼 于 2013-3-10 16:31 编辑
回复 3# apang
老师您好!您写的这段批处理代码,是逐行提取各列特定位置的数值,第一次做统计时确实需要,但是当有数据更新时,就只需要提取第一行的各列特定位置的数值了,此时该批处理代码还是会逐行提取,颇费时间。老师能否略改代码,再给出一个仅提取第一行各列特定位置数值的批处理代码?恳望老师帮助!
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |