标题: [文本处理] 如何移动指定的某列数据到最后、合计指定列的数据 [打印本页]
作者: youaoyi 时间: 2008-9-2 17:00 标题: 如何移动指定的某列数据到最后、合计指定列的数据
在经过群中珊瑚海朋友指点后, 琢磨着将批处理做成以下这个样子,
由于自己不懂如何将变量"%wjmc%"写入到for语句中才能正常有效,
只好使用了复制来复制去的笨方法,各位见笑了。
@echo off
cls
mode con cols=40 lines=16 &color 0B
title 指定文本列置于每行最后一列
cls
echo.
echo.
echo 请把要处理的TXT文本文件拖到本窗口
set wjmc=:
echo.
set /p wjmc= 待处理的文件为:
set "wjmc=%wjmc:"=%"
echo.
echo.
::::::::::::::::::::::::::::::::::::::::::::::::::::::
setlocal enabledelayedexpansion
copy "%wjmc%" c:\temp_hh.txt
for /f "tokens=1,2,3,4,5,6,7,8 delims=|" %%a in (c:\temp_hh.txt) do echo %%a-%%b-%%c-%%d-%%e-%%g-%%h-%%f >>c:\temp_hh2.txt
for /f "delims=" %%m in (c:\temp_hh2.txt) do (
set var=%%m
set "var=!var:-=|!"
echo !var! >>c:\temp_hh3.txt
)
move /Y c:\temp_hh3.txt "%wjmc%"_换列.txt
pause
del c:\temp_hh.txt>nul2>nul
del c:\temp_hh2.txt>nul2>nul
echo 结束
pause
目的就是可以把一个文本中的某一列数据移动到各行的最后.
对于下面这个样本, 这个批处理是可以完成的(执行后"需要移动到最后的字段"被放到了文本的最后).
1|200757|单方合同|其它|殷顺|45665需要移动到最后的字段|4000.0|
2|200752|合同|经济原因|宝举|3454534534需要移动到最后的字段|10232.35|
3|202810|合同|经济原因|传龙|56546需要移动到最后的字段|479.0|
4|202810|单方合同|经济原因|传龙|2222需要移动到最后的字段|479.0|
5|202810|合同|其它原因|传龙|4343需要移动到最后的字段|23.72|
6|202810|合同|经济原因|传龙|5454667需要移动到最后的字段|23.72|
问题是手头上有几百个类似的文本, 各行数据的列数并不一定是7组,
因此想要移动的数据也不一定在第6列,比如下面的样本2、样本3,
样本2:
1|200757|单方合同|其它|殷顺|45665需要移动到最后的字段|4000.0|其它|殷顺|200757|单方合同
2|200752|合同|经济原因|宝举|3454534534需要移动到最后的字段|10232.35|其它|殷顺|200757|单方合同
3|202810|合同|经济原因|传龙|56546需要移动到最后的字段|479.0|其它|殷顺|200757|单方合同
4|202810|单方合同|经济原因|传龙|2222需要移动到最后的字段|479.0|其它|殷顺|200757|单方合同
5|202810|合同|其它原因|传龙|4343需要移动到最后的字段|23.72|其它|殷顺|200757|单方合同
6|202810|合同|经济原因|传龙|5454667需要移动到最后的字段|23.72|其它|殷顺|200757|单方合同
样本3:
1|200757|45665需要移动到最后的字段|4000.0|其它|殷顺|200757|单方合同
2|200752|3454534534需要移动到最后的字段|10232.35|其它|殷顺|200757|单方合同
3|202810|56546需要移动到最后的字段|479.0|其它|殷顺|200757|单方合同
4|202810|2222需要移动到最后的字段|479.0|其它|殷顺|200757|单方合同
5|202810|4343需要移动到最后的字段|23.72|其它|殷顺|200757|单方合同
如何才能将上述批处理修改成可以由用户指定想要移动的列, 实现通用呢?
请予以指点。
2008年9月4日追加问题:(仍是上述三个样本)
如果不移动指定列的话,能否将指定列的数值累加求得合计数?
需要合计的数值在不同文本中处在不同的列,
因此仍需要允许用户任意指定想要求和的数据在哪一列中,
比如样本1,需要求和的数值在最后一列;样本2,需要求和的数值在在第7列; 样本3,需要求和的数值在第4列.....等等
这个问题需要运行速度比较快才行,是不是借用第三方工具并不重要。
[ 本帖最后由 youaoyi 于 2008-9-4 22:22 编辑 ]
作者: youaoyi 时间: 2008-9-2 17:17
还有就是每个文本中的数据量很大,
需要稍微追求一点执行效率,不知道类似SED这样的第三方命令能否做到,
因为之前在本坛请教的一个问题,用SED命令执行速度超快,
可对于一楼的这个问题,我是怎么也想不明白应该怎么写了。
自己弄的这个复制、删除、再复制、再删除的笨方法,自己都受不了,怎么才能将这个"%wjmc%"代入到for公式中去呢?
[ 本帖最后由 youaoyi 于 2008-9-2 17:35 编辑 ]
作者: batman 时间: 2008-9-2 17:39
- @echo off&setlocal enabledelayedexpansion
- set /p file=请将要处理的文本拖放到这里:
- echo.&set /p lie=请输入要处理的列数:
- cls&echo.
- for /f "usebackq delims=" %%a in ("%file%") do (
- set "str=%%a"&set "str=!str:|= !"&set "n=0"
- for %%i in (!str!) do (
- set /a n+=1
- if !n! equ %lie% (
- set "var=%%i"
- ) else (
- set /p=%%i^|<nul
- )
- )
- set /p=!var!<nul&echo.
- )
- pause>nul
复制代码
作者: pusofalse 时间: 2008-9-2 18:11
如果你是把文件直接拖到CMD窗口,那么BATMAN版主的代码有点小错误,
for /f "usebackq delims=" %%a in ("%file%") do ....
应该把()中的""去掉。
作者: youaoyi 时间: 2008-9-2 18:30
谢谢 batman 斑竹、pusofalse 斑竹以及群中诸位兄弟的帮忙,
目前对小容量样本的测试完全没有问题,
明日换个大个头的文本 ,测试后再来汇报结果,
谢谢各位了.
[ 本帖最后由 youaoyi 于 2008-9-2 18:32 编辑 ]
作者: terse 时间: 2008-9-2 21:26
- @echo off&setlocal enabledelayedexpansion
- set/p m=输入列:
- for /f "tokens=%m% delims=|" %%i in (a.txt) do call:lp "%%i"
- pause&goto :eof
- :lp
- for /f "%skip% tokens=* delims=|" %%i in (a.txt) do (
- set str=%%i
- set str=!str:%~1^|=!
- set/a n+=1&set skip=skip=!n!
- echo !str!^|%~1&goto :eof
- )
复制代码
作者: youaoyi 时间: 2008-9-3 15:45
汇报: 测试了一个300多兆的文本
没等到结束, 运行了半个小时 ctrl _c 退出了
看了下已处理的文档,大约处理了50兆、60万条数据。
速度尚可,但处理一个文档还是要超过三个小时,
如有高人还能加速,望不吝赐教。
六楼的批处理运行时报告内存不足,无法运行。
再次谢谢大家了。
[ 本帖最后由 youaoyi 于 2008-9-3 16:13 编辑 ]
作者: pusofalse 时间: 2008-9-3 16:02
借助第三方工具吧,300M的文本,用纯批不管怎样写,效率总是提不上去。请教论坛的高人吧。
作者: Batcher 时间: 2008-9-3 16:51 标题: 回复 6楼 的帖子
如果要移动的列中包含特殊字符,用set替换的时候会出问题吧?
作者: youaoyi 时间: 2008-9-3 17:31
要移动的列 全部为两个"|"之间的纯数字,
是用来表示金额的.
[ 本帖最后由 youaoyi 于 2008-9-3 17:34 编辑 ]
作者: namejm 时间: 2008-9-3 17:37
问题的关键是:"把一个文本中的某一列数据移动到各行的最后",这个某一列究竟有什么规律?如果只是举例,而不用文字描述的话,别人是没法了解其中的规律的。如果你不把关键的条件告诉别人,别人写出来的代码总是满足不了你的需求,更谈不上通用。
作者: youaoyi 时间: 2008-9-4 08:45 标题: 回复 11楼 的帖子
正是因为待移动的一列没有什么规律才非常棘手,
因为有非常多的TXT文本, 待移动的数据都位于不同的列。
(不过同一个TXT文本,待移动的数据都是在相同的一列中);
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
只能象三楼batman斑竹那样让用户自行输入数字来指定待移动的数据位于第几列.
-------------> :: echo.&set /p lie=请输入要处理的列数:
三楼的批处理已经能够完美完成所需工作, 只是在处理巨大文本时速度有些慢了。
[ 本帖最后由 youaoyi 于 2008-9-4 08:49 编辑 ]
作者: 随风 时间: 2008-9-4 19:47
第三放工具 sed 应该可以解决效率问题。
论坛第三放工具中有下载的。
具体代码,发帖求助,我在网吧,没有sed ,不能测试。。。
作者: youaoyi 时间: 2008-9-4 22:23
2008年9月4日追加问题:(仍是一楼的三个样本)
如果不移动指定列的话,能否将指定列的数值累加求得合计数?
需要合计的数值在不同文本中处在不同的列,
因此仍需要允许用户任意指定想要求和的数据在哪一列中,
比如样本1,需要求和的数值在最后一列;样本2,需要求和的数值在在第7列;
样本3,需要求和的数值在第4列...........等等
这个问题需要运行速度比较快才行,是不是借用第三方工具并不重要。
作者: Batcher 时间: 2008-9-4 22:34
数据列累加问题很容易实现。
如果用批处理,要考虑批处理能够计算的极值。
如果允许用第三方工具,根据CU前人讨论的结果,gawk应该是最快的。
作者: youaoyi 时间: 2008-9-4 23:35
http://chinalinuxpub.com/doc/pro/gawk.html 这里介绍的这个 gawk 吗?
看了半天,没有理出一点头绪,甚至连举例中的语句都没有执行成功.....惨遭失败.....
在这里下载的 gawk http://www.klabaster.com/progs/gawk32.zip
[ 本帖最后由 youaoyi 于 2008-9-4 23:38 编辑 ]
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |