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

[文本处理] 【已解决】批处理:提取各列特定位置的数值

附件中,第一列是时序,第二列--第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文本的数据格式,如同去除时序的附件文本。

不知道说明白没有。恳望得到大师的帮助!
1

评分人数

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

提取出来的这么多数值在保存的时候按照什么格式,和附件的数据格式一样吗,
比如你说的0000001的数值是12,查询后提取到11,这个11直接替换原来12的位置呢还是怎么说?

TOP

本帖最后由 apang 于 2013-3-4 11:07 编辑
  1. Set FSO = CreateObject("Scripting.FileSystemObject")
  2. Set File = FSO.OpenTextFile("a.txt")
  3. T = Time
  4. Do Until File.atEndOfStream
  5.    Text = File.ReadLine
  6.    If RegEx <> "" Then     '排除空行
  7.       A = Split(RegEx," ")
  8.       m = UBound(A)         'm=列数
  9.       ReDim PreServe B(m,n) '申明数组B
  10.       For i = 0 to m :B(i,n) = A(i) :Next '数组B赋值
  11.       n = n + 1 '行数
  12.    End If
  13. Loop
  14. n = n - 1
  15. For i = 1 to m      'm=列数
  16.    For j = 0 to n   'n=行数
  17.       flag = 1
  18.       For k = j + 1 to n
  19.          If B(i,j) = B(i,k) Then   '相等则赋值为上一行的值
  20.             flag = 0 :B(i,j) = B(i,k-1) :Exit For
  21.          End If
  22.       Next
  23.       If flag Then B(i,j) = " "    '不相等则赋值为空格
  24.    Next
  25. Next
  26. For i = 0 to n  '写入文件
  27.    Str = ""
  28.    For j = 1 to m : Str = Str & vbTab & B(j,i) : Next
  29.    FSO.OpenTextFile("b.txt",8,true).WriteLine B(0,i) & Str
  30. Next
  31. MsgBox T & vbLf & Time
  32. Function RegEx()
  33.    Set Re = New RegExp
  34.    Re.Pattern = "\s+"
  35.    Re.Global = True
  36.    RegEx = Trim(Re.Replace(Text," "))
  37. End Function
复制代码
保存为test.vbs,不知道能否满足要求,试一下
2

评分人数

TOP

P来下
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1*" %%i in (a.txt) do (
  3.     set /a num+=1,n=0
  4.     set _!num!=%%i
  5.     for %%a in (%%j) do (
  6.         set /a n+=1
  7.         for %%b in (!n!) do set $%%b=!$%%b! %%a
  8.     )
  9. )
  10. for /l %%i in (1 1 %n%) do (
  11.     for /l %%j in (1 1 %num%) do (
  12.         for /f "tokens=1*" %%a in ("!$%%i!") do (
  13.             set s=&set f=%%a&set "$%%i=%%b"
  14.                for %%c in (%%b) do (
  15.                    if not defined s (
  16.                       if %%a equ %%c set s=!f!
  17.                       set f=%%c
  18.                    )
  19.                )
  20.         )
  21.                       set #%%j=!#%%j! !s!
  22.     )
  23. )
  24. (for /l %%i in (1 1 !num!) do echo !_%%i!!#%%i!)>a2.txt
  25. pause
复制代码
2

评分人数

TOP

回复 3# apang


您的代码,运算正确,速度迅速,赞一下!也羡慕一把,要是我自己也会写,多好!
这个代码,解决的是一列数值中,首位一个数值与下相同,则取第一个与之相同数值的前一个数,如果扩展一下,首两个数值与下两个数值相同,则取第一个与之相同的前一个数值,即如:
8
5
6
3
2
1
8
5
首两个数值是8 5,该列第一个与8 5这两个数相同的前一个数值是1,则取之。
如若这样,代码该修改何处?
我明白了这点,首三个数值、首四个数值......等,自己就可以扩展运用了。
盼望大师指点!

TOP

回复 5# 思想之翼

    两行同时比较,可以将中间那段循环改成下面的:
  1. For i = 1 to m '总列数
  2.    For j = 0 to n '总行数
  3.       f = 1
  4.       For k = j + 1 to n
  5.          If j + 1 <= n and k + 1 <= n Then
  6.             If b(i,j) = b(i,k) and b(i,j+1) = b(i,k+1) Then '有重复则赋值为上一行的值
  7.                f = 0 :b(i,j) = b(i,k-1) :Exit For
  8.             End If
  9.          End If
  10.       Next
  11.       If f Then b(i,j) = " "  '没有重复则赋值为空格
  12.    Next
  13. Next
复制代码

TOP

回复 3# apang

附件中的样本运行该代码时出错,运行代码得到的b.txt,和a.txt的数值一样,代码没有运行。是a.txt中有空格空行,还是数值间距的问题?烦请大师帮助查看一下,好吗?
出错样本中附保存为test.vbs的代码、a.txt文本。

TOP

回复 7# 思想之翼


    好吧,3#修改了,试下

TOP

本帖最后由 思想之翼 于 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

TOP

回复 9# 思想之翼

vbTab换成chr(32)

TOP

本帖最后由 思想之翼 于 2013-3-10 16:31 编辑

回复 3# apang


    老师您好!您写的这段批处理代码,是逐行提取各列特定位置的数值,第一次做统计时确实需要,但是当有数据更新时,就只需要提取第一行的各列特定位置的数值了,此时该批处理代码还是会逐行提取,颇费时间。老师能否略改代码,再给出一个仅提取第一行各列特定位置数值的批处理代码?恳望老师帮助!

TOP

返回列表