标题: [文本处理] [已解决]批处理如何将多个文本按相同名称合并为单文本? [打印本页]
作者: w96692 时间: 2010-4-29 10:34 标题: [已解决]批处理如何将多个文本按相同名称合并为单文本?
在我的电脑“f”盘下“zhubi”文件夹内有名称为以下的,共计260个文本
内盘1.txt..............内盘31.txt
外盘1.txt..............外盘31.txt
内盘笔1.txt..............内盘笔31.txt
外盘笔1.txt..............外盘笔31.txt
委买1.txt..............委买31.txt
委卖1.txt..............委卖31.txt
委买笔1.txt..............委买笔31.txt
委卖笔1.txt..............委卖笔31.txt
内盘成交笔数.txt
内盘成交量.txt
内盘单笔最大成交量.txt
外盘成交笔数.txt
外盘成交量.txt
外盘单笔最大成交量.txt
委托买入总量.txt
委买总笔.txt
委买单笔最大成交量.txt
委托卖出总量.txt
委卖总笔.txt
委卖单笔最大成交量.txt
所有文本格式都一样,如以下,第一列为名称,第二列为日期,第三列为数值(所有第一列名称和第二列日期都一样,只有第三列数值不同)
SH600004 2010-04-28 37381
SH600005 2010-04-28 101010
SH600006 2010-04-28 36716
SH600007 2010-04-28 16350
SH600008 2010-04-28 45580
SH600009 2010-04-28 162257
SH600010 2010-04-28 83726
SH600011 2010-04-28 21314
SH600012 2010-04-28 67743
SH600016 2010-04-28 0
SH600017 2010-04-28 86413
SH600018 2010-04-28 55453
SH600019 2010-04-28 102978
SH600020 2010-04-28 25946
SH600021 2010-04-28 28294
SH600022 2010-04-28 53404
SH600026 2010-04-28 38750
SH600027 2010-04-28 0
SH600028 2010-04-28 197883
我想将这260个文件按第一列的名称合并成一个文件,我每天都用excel做同样的工作,太繁琐了,我想做个批处理,合并后文件格式如下(每列数值前为原始文本名称)
名称 日期 内盘1 内盘2 内盘3 内盘4.................
SH600004 2010-04-28 37381 16350 16350 16350.................
SH600005 2010-04-28 101010 5650 66350 350................
SH600006 2010-04-28 36716 5350 46350 616350................
[ 本帖最后由 w96692 于 2010-4-30 10:24 编辑 ]
作者: hanyeguxing 时间: 2010-4-29 17:27
是否按楼主在1楼提供的文本顺序进行合并?
以下批处理的文本处理顺序是按楼主提供的列表顺序进行:- @echo off&setlocal enabledelayedexpansion
- set "a= "
- set "han=F:\zhubi\"
- set "ye=F:\zhubi\合并%date%.txt"
- set "gu=内盘成交笔数 内盘成交量 内盘单笔最大成交量 外盘成交笔数 外盘成交量 外盘单笔最大成交量 委托买入总量 委买总笔 委买单笔最大成交量 委托卖出总量 委卖总笔 委卖单笔最大成交量"
- for %%a in (内盘 外盘 内盘笔 外盘笔 委买 委卖 委买笔 委卖笔) do for /l %%b in (1,1,31) do call:xing "%%a%%b"
- for %%a in (%gu%) do call:xing "%%a"
- echo.开始合并到文本"%ye%"
- >"%ye%" echo.名称%a%日期!xing!
- for /f "usebackq tokens=1,2" %%a in ("%han%内盘1.txt") do >>"%ye%" echo.%%a%a%%%b!#%%a!
- echo.操作已完成&pause&exit
- :xing
- set "xing=!xing!%a%%~1"
- set "b=%han%%~1.txt"
- echo.正在预处理%b%...
- for /f "usebackq tokens=1,3" %%a in ("%b%") do set "#%%a=!#%%a!%a%%%b"
复制代码
说明:
本批处理正常运行可能受到此限制:最大单个环境变量大小为 8192 字节。所有变量的最大环境变量的总和大小(包括变量名和等号)为 65,536 KB。
变量a设置制表符为值,即set "a= "中的等号后面不是空格,是一个制表符。
变量han设置文本所在目录路径,允许该路径存在空格。
变量ye设置合并后文本的路径和文件名。最后合并的文本名例如为“F:\zhubi\合并2010-04-29 星期四.txt”。
变量gu设置不循环的文本。
[ 本帖最后由 hanyeguxing 于 2010-4-30 00:10 编辑 ]
作者: w96692 时间: 2010-4-29 22:47
原帖由 hanyeguxing 于 2010-4-29 17:27 发表
是否按楼主在1楼提供的文本顺序进行合并?
以下批处理的文本处理顺序是按楼主提供的列表顺序进行:@echo off&setlocal enabledelayedexpansion
set "a= "
set "han=F:\zhubi\"
set "ye=F:\zhubi\合并%date%.tx ...
顺序就按我给出的就行(1-31)那样排列,无序号的文本放在末尾。
首先感谢您的帮助,可是不知为什么,运行代码后无任何反映(只出了一个黑框,无任何内容显示),也没有合并文件。
作者: sgaizxt001 时间: 2010-4-29 23:17
copy /b *.txt a.txt 可以把这些文本里的所有内容合并到a.txt,但是好象前缀都一样啊。比如:
内盘笔4
SH600000 2010-04-29 1935
SH600004 2010-04-29 324
SH600005 2010-04-29 1020
SH600007 2010-04-29 65
SH600008 2010-04-29 443
SH600009 2010-04-29 1907
SH600010 2010-04-29 676
SH600011 2010-04-29 156
委买1
SH600000 2010-04-29 265273
SH600004 2010-04-29 35524
SH600005 2010-04-29 142144
SH600007 2010-04-29 9673
SH600008 2010-04-29 47285
SH600009 2010-04-29 238261
SH600010 2010-04-29 129699
SH600011 2010-04-29 18959
关键是第3列要怎么弄?
作者: hanyeguxing 时间: 2010-4-29 23:34
测试2楼的代码没有问题:
1,由于原先未加入进度显示,造成缺乏实时显示状态。针对这个问题,已对2楼代码进行修改。
2,随着变量的处理量变大,速度会越来越慢。实际测试,完成整个操作需要24分50秒。
3,优点是不使用临时文件。
4,按指定的文本顺序进行处理。
[ 本帖最后由 hanyeguxing 于 2010-4-30 00:50 编辑 ]
作者: namejm 时间: 2010-4-30 00:34
看了楼主的描述,楼主的需求似乎是这样的:
1、有260个文本文件,每个文件有3列数据;
2、在这些文本文件中,每个文件对应行上的第1列和第2列数据相同;
3、需要把这260个文件中的所有数据都汇总到一个文件中,从第3列起,每列字段以文件名作为字段名,以对应行上第3列的数据作为相应列字段的数据加以保存;
4、第3列起的列字段顺序,以文件名中1~31的升序排列,文件名前缀相同的放一块,没有相同前缀的放后面;
如果我这个描述准确、完整地归纳了楼主的意思的话,可以使用下面的代码生成中间数据,然后导入excel中加以处理:- @echo off
- set t=%time%
- (
- set /p=名称 日期<nul
- for %%i in (*.txt) do set /p =%%~ni<nul
- echo.
- for /f "tokens=1,2" %%i in (委买1.txt) do (
- echo 正在处理 %%i>con
- set /p=%%i %%j<nul
- for /f "tokens=3" %%x in ('findstr /bc:"%%i" *.txt') do set /p=%%x<nul
- echo.
- )
- echo.
- )>result
- start notepad.exe result
- cls
- echo 处理完毕
- echo %t%
- echo %time%
- pause
复制代码
以上代码需放在F盘Zhubi目录下运行,思路是:
1、用 for 语句读取当前目录下的所有 txt 文件名,生成行标题;
2、根据 委买1.txt 文件里第1列的数据,在所有txt文件中查找以 委买1.txt 文件中第1列数据打头的对应行上第3列的数据,拼接起来,作为新行保存。只要保证每个文件对应行上的第1列和第2列绝对相同,没有丝毫错位,则 委买1.txt 可以换成任意一个存在的文本文件名,实际上,这也是本代码能够实现楼主意图的前提。
通过以上代码,生成的数据保存在名为result的文本文件中,每列数据以空格分隔。考虑到批处理中每行能处理的最大字节数有限制(约为8192字节),所以每列数据以单个空格分隔,这样,假设每列数值在10字符以内,则每个数值行的长度约为(262*10+261)字节,而标题行的字符数可能是数值行长度的1.5倍,单行数据长度不会超限。
需要注意的是,数据处理结果文件绝对不能保持为.txt后缀,否则,会导致重复统计。
另外,当文件名的序号超过9的时候,最终结果的字段名不能完全按照1~31这样的升序排列,而是按照1,10~19,2,20~29,3,30,31这样的顺序排列,需要在excel中自行调整顺序。
导入excel时,请以空格作为分隔符号切分文本。
在本人机器上的测试结果,用楼主提供的12个文本,耗时3分钟左右,照此速度推测,260个文件约需1小时左右。本人机器配置为:主频1.6GHz、512M内存,SP3系统。
作者: sgaizxt001 时间: 2010-4-30 07:32
哦,明白你的意思了。不过楼上的代码已经够精简了,不继续丢人了
作者: w96692 时间: 2010-4-30 07:51
首先感谢大家的帮助,我的求助本意是做个批处理不用每次都复制到文件夹执行,(日复一日也挺麻烦的),版主的很好,就是也需要复制到文件夹内,如果能指定目录就好了
[ 本帖最后由 w96692 于 2010-4-30 08:21 编辑 ]
作者: w96692 时间: 2010-4-30 08:11 标题: 回复 6楼 的帖子
用了您的代码,也很快处理完,但是也需要复制,如果能够不用复制就好了(我每天只处理f盘zhubi文件夹,这是固定的),谢谢您
[ 本帖最后由 w96692 于 2010-4-30 08:19 编辑 ]
作者: more 时间: 2010-4-30 09:19
能用excel完成的就用excel吧,效率不在同一个级别上...
作者: namejm 时间: 2010-4-30 10:03
修改一下6楼的代码,使得批处理可以放在任意位置,但是要处理的目录除外(可以放在要处理目录的子目录下),并且,生成的结果保存在批处理文件当前目录下:- @echo off
- set t=%time%
- set "olddir=%cd%"
- cd /d f:\zhubi
- (
- set /p=名称 日期<nul
- for %%i in ( *.txt) do set /p =%%~ni<nul
- echo.
- for /f "tokens=1,2" %%i in (委买1.txt) do (
- echo 正在处理 %%i>con
- set /p=%%i %%j<nul
- for /f "tokens=3" %%x in ('findstr "%%i" *.txt') do set /p=%%x<nul
- echo.
- )
- echo.
- )>"%olddir%\result.txt"
- start "" "%olddir%\result.txt"
- cls
- echo 处理完毕
- echo %t%
- echo %time%
- pause
复制代码
再来一个略为提高速度的代码,但是需要生成临时文件,该代码的思路是先把所有文本合并到一个临时文件中,然后读取该临时文件的内容,从而避免读取多个文件,使得速度略有提升:- @echo off
- set "olddir=%cd%"
- cd /d f:\zhubi
- set t=%time%
- cd.>"%olddir%\tmp.txt"
- for %%i in (*.txt) do (
- call set str1=%%str1%%+%%i
- call set str2=%%str2%% %%~ni
- )
- copy %str1:~1% "%olddir%\tmp.txt"
- echo 名称 日期 %str2%>"%olddir%\result.txt"
- cls
- (for /f "tokens=1,2" %%i in (委买1.txt) do (
- echo 正在处理 %%i>con
- set /p=%%i %%j<nul
- for /f "tokens=3" %%x in ('findstr /ib "%%i" "%olddir%\tmp.txt"') do (
- set /p=%%x<nul
- )
- echo.
- ))>>"%olddir%\result.txt"
- start "" "%olddir%\result.txt"
- cls
- echo 处理完毕
- echo %t%
- echo %time%
- pause
复制代码
作者: w96692 时间: 2010-4-30 10:24
原帖由 namejm 于 2010-4-30 10:03 发表
修改一下6楼的代码,使得批处理可以放在任意位置,但是要处理的目录除外(可以放在要处理目录的子目录下),并且,生成的结果保存在批处理文件当前目录下:@echo off
set t=%time%
set "olddir=%cd%"
cd /d f ...
谢谢管理员,虽然比excel慢点,但省事了,我是又笨又懒啊,再次感谢
作者: w96692 时间: 2010-4-30 10:26
原帖由 more 于 2010-4-30 09:19 发表
能用excel完成的就用excel吧,效率不在同一个级别上...
是啊,excel处理所有文件也就20秒,批处理需要几分钟啊,但省事好多,谢谢大家!!!!
作者: namejm 时间: 2010-4-30 10:31
用vba写一段excel宏应当能满足楼主的懒惰需求,可惜我不会写vba,不知有谁愿意尝试一下。
作者: more 时间: 2010-5-2 07:04
如果要做成Excel的话,本人愿意一试...否则用vbs,效率也比批处理高得多.
[ 本帖最后由 more 于 2010-5-2 07:34 编辑 ]
作者: more 时间: 2010-5-2 12:43
帖个VBA的.- Option Explicit
-
- Sub Try()
- Dim lngRow As Long, i As Integer, objFso As Object, objFolder As Object, arrData, _
- objFl As Object, objOpFl As Object, strPth As String, intCol As Integer, strTime As String, intSh As Integer
-
- strPth = "f:\zhubi" '在此指定要处理的目标文件夹
- Set objFso = CreateObject("scripting.filesystemobject")
- If objFso.folderexists(strPth) = False Then
- MsgBox "文件夹" & Chr(34) & strPth & Chr(34) & "不存在!!!" & Chr(10) & vbCrLf & _
- "请按 Alt + F11 打开 VBE 编辑器指定新的路径...", 48, " :("
- Set objFso = Nothing
- Exit Sub
- End If
- strTime = Time
- intSh = 1
- Sheets(intSh).Select
- Application.ScreenUpdating = False
- Range("a1:iv65536").ClearContents
- Cells(1, 1) = "名称": Cells(1, 2) = "日期"
- Set objFolder = objFso.getfolder(strPth)
- Set objOpFl = objFso.opentextfile(strPth & "\" & "内盘笔4.txt", 1)
- lngRow = 1: intCol = 2
- Do Until objOpFl.atendofstream
- arrData = Split(objOpFl.readline, vbTab, -1, 1)
- lngRow = lngRow + 1
- Cells(lngRow, 1) = arrData(0): Cells(lngRow, 2) = arrData(1)
- Loop
- objOpFl.Close
- For Each objFl In objFolder.Files
- If objFso.GetExtensionName(strPth & "\" & objFl.Name) = "txt" Then
- Set objOpFl = objFso.opentextfile(strPth & "\" & objFl.Name)
- lngRow = 1: intCol = intCol + 1
- If intCol > 256 Then
- intCol = 1: intSh = intSh + 1
- For i = 1 To 256
- Columns(i).AutoFit
- Next i
- Sheets(intSh).Select
- End If
- Cells(1, intCol) = objFso.GetbaseName(objFl.Name)
- Do Until objOpFl.atendofstream
- arrData = Split(objOpFl.readline, vbTab, -1, 1)
- lngRow = lngRow + 1
- Cells(lngRow, intCol) = arrData(2)
- Loop
- objOpFl.Close
- End If
- Next
- Set objFso = Nothing: Set objFolder = Nothing: Set objOpFl = Nothing
- For i = 1 To Range("iv1").End(xlToLeft).Column
- Columns(i).AutoFit
- Next i
- Application.ScreenUpdating = True
- MsgBox strTime & vbCrLf & Time & Chr(10) & "Done!", 0, "Right?"
- End Sub
复制代码
在本机上就楼主上传的附件,用namejm的批代码要几分钟时间,而VBA仅一两秒钟,效率简直一个天一个地...
代码贴错了,改一改...
作者: 随风 时间: 2010-5-2 22:57
又是一个挑战效率的文本题
想起好像有个 Hitme 前辈,
初学批处理时看到他的代码经常使用大量的临时文件来完成任务,现也模仿下 ^_^
我理解题意为:结果文件将会有262列,每列为某单个文件的第3列
思路:
先生成260个临时文件,以文本的第1、2列为文件名,第3列为内容
再将所有文件合为一个文件,将单个文件的所有内容合为一行即可
创建测试环境太麻烦,故代码未经测试,只是想当然 ^_^
若楼主回头看见此帖,还请测试后回复一下结果是否正确,且耗时如何。
此代码只有针对性没有通用性,是专对楼主题意解的。- @echo off
- set var=内盘 外盘 内盘笔 外盘笔 委买 委卖 委买笔 委卖笔
- md tem
- for %%i in (%var%) do (
- for /l %%L in (1 1 31) do (
- for /f "tokens=1-3" %%a in (%%i%%L.txt) do >>"tem\%%a %%b.txt" echo %%c
- )
- )
- set num=内盘成交笔数 内盘成交量 内盘单笔最大成交量 外盘成交笔数 外盘成交量 外盘单笔最大成交量
- set num=%num% 委托买入总量 委买总笔 委买单笔最大成交量 委托卖出总量 委卖总笔 委卖单笔最大成交量
- set /p=名称 日期 %var% %num%<nul>test.txt
- for %%i in (%num%) do (
- for /f "tokens=1-3" %%a in (%%i.txt) do >>"tem\%%a %%b" echo %%c
- )
- set lj=%cd%
- cd/d tem
- for %%i in (*.txt) do (
- set/p=%%~ni<nul>>"%lj%\test.txt"
- for /f "usebackq delims=" %%a in ("%%i") do set /p= %%a<nul>>"%lj%\test.txt"
- echo;
- )
- cd..
- rd /s /q tem
- start test.txt
复制代码
[ 本帖最后由 随风 于 2010-5-3 18:04 编辑 ]
作者: w96692 时间: 2010-5-3 14:01
原帖由 more 于 2010-5-2 12:43 发表
帖个VBA的.Option Explicit
Sub Try()
Dim lngRow As Long, i As Integer, objFso As Object, objFolder As Object, arrData, _
objFl As Object, objOpFl As Object, strPth As String, intCol As ...
感谢关注,附上测试结果,excel2007运行19秒完成所有文件,还未看正确性,就效率而言,牛!!!!!
[ 本帖最后由 w96692 于 2010-5-3 14:02 编辑 ]
作者: w96692 时间: 2010-5-3 14:13
原帖由 随风 于 2010-5-2 22:57 发表
又是一个挑战效率的文本题
想起好像有个 Hitme 前辈,
初学批处理时看到他的代码经常使用大量的临时文件来完成任务,现也模仿下 ^_^
我理解题意为:结果文件将会有262列,每列为某单个文件的第3列
思路:
先生 ...
我看您理解的意思也对,但代码不能运行,不知何故?(放到别的盘下运行出一个有表头的txt文本,放到zhubi文件夹下不运行)
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |