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

[文本处理] 如何移动指定的某列数据到最后、合计指定列的数据

在经过群中珊瑚海朋友指点后,  琢磨着将批处理做成以下这个样子,
由于自己不懂如何将变量"%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 编辑 ]

还有就是每个文本中的数据量很大,
需要稍微追求一点执行效率,不知道类似SED这样的第三方命令能否做到,
因为之前在本坛请教的一个问题,用SED命令执行速度超快,
可对于一楼的这个问题,我是怎么也想不明白应该怎么写了。

自己弄的这个复制、删除、再复制、再删除的笨方法,自己都受不了,怎么才能将这个"%wjmc%"代入到for公式中去呢?

[ 本帖最后由 youaoyi 于 2008-9-2 17:35 编辑 ]

TOP

  1. @echo off&setlocal enabledelayedexpansion
  2. set /p file=请将要处理的文本拖放到这里:
  3. echo.&set /p lie=请输入要处理的列数:
  4. cls&echo.
  5. for /f "usebackq delims=" %%a in ("%file%") do (
  6.      set "str=%%a"&set "str=!str:|= !"&set "n=0"
  7.      for %%i in (!str!) do (
  8.            set /a n+=1
  9.            if !n! equ %lie% (
  10.                    set "var=%%i"
  11.                    ) else (
  12.                    set /p=%%i^|<nul
  13.           )
  14.      )
  15.      set /p=!var!<nul&echo.
  16. )
  17. pause>nul
复制代码
***共同提高***

TOP

如果你是把文件直接拖到CMD窗口,那么BATMAN版主的代码有点小错误,

for /f "usebackq delims=" %%a in ("%file%") do ....
应该把()中的""去掉。
心绪平和,眼藏静谧。

TOP

谢谢 batman 斑竹、pusofalse 斑竹以及群中诸位兄弟的帮忙,

目前对小容量样本的测试完全没有问题,

明日换个大个头的文本 ,测试后再来汇报结果,

谢谢各位了.

[ 本帖最后由 youaoyi 于 2008-9-2 18:32 编辑 ]

TOP

  1. @echo off&setlocal enabledelayedexpansion
  2. set/p m=输入列:
  3. for /f "tokens=%m% delims=|" %%i in (a.txt) do call:lp "%%i"
  4. pause&goto :eof
  5. :lp
  6. for /f "%skip% tokens=* delims=|" %%i in (a.txt) do (
  7.     set str=%%i
  8.     set str=!str:%~1^|=!
  9.     set/a n+=1&set skip=skip=!n!
  10.     echo !str!^|%~1&goto :eof
  11. )
复制代码

TOP

汇报:  测试了一个300多兆的文本

没等到结束, 运行了半个小时 ctrl _c 退出了

看了下已处理的文档,大约处理了50兆、60万条数据。

速度尚可,但处理一个文档还是要超过三个小时,

如有高人还能加速,望不吝赐教。

六楼的批处理运行时报告内存不足,无法运行。

再次谢谢大家了。

[ 本帖最后由 youaoyi 于 2008-9-3 16:13 编辑 ]

TOP

借助第三方工具吧,300M的文本,用纯批不管怎样写,效率总是提不上去。请教论坛的高人吧。
心绪平和,眼藏静谧。

TOP

回复 6楼 的帖子

如果要移动的列中包含特殊字符,用set替换的时候会出问题吧?
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

要移动的列   全部为两个"|"之间的纯数字,
是用来表示金额的.

[ 本帖最后由 youaoyi 于 2008-9-3 17:34 编辑 ]

TOP

  问题的关键是:"把一个文本中的某一列数据移动到各行的最后",这个某一列究竟有什么规律?如果只是举例,而不用文字描述的话,别人是没法了解其中的规律的。如果你不把关键的条件告诉别人,别人写出来的代码总是满足不了你的需求,更谈不上通用。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

回复 11楼 的帖子

正是因为待移动的一列没有什么规律才非常棘手,

因为有非常多的TXT文本, 待移动的数据都位于不同的列。

(不过同一个TXT文本,待移动的数据都是在相同的一列中);

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

只能象三楼batman斑竹那样让用户自行输入数字来指定待移动的数据位于第几列.

------------->  :: echo.&set /p lie=请输入要处理的列数:

三楼的批处理已经能够完美完成所需工作, 只是在处理巨大文本时速度有些慢了。

[ 本帖最后由 youaoyi 于 2008-9-4 08:49 编辑 ]

TOP

第三放工具 sed 应该可以解决效率问题。
论坛第三放工具中有下载的。
具体代码,发帖求助,我在网吧,没有sed ,不能测试。。。
技术问题请到论坛发帖求助!

TOP

2008年9月4日追加问题:(仍是一楼的三个样本)  

如果不移动指定列的话,能否将指定列的数值累加求得合计数?
需要合计的数值在不同文本中处在不同的列,
因此仍需要允许用户任意指定想要求和的数据在哪一列中,

比如样本1,需要求和的数值在最后一列;样本2,需要求和的数值在在第7列;  
样本3,需要求和的数值在第4列...........等等

这个问题需要运行速度比较快才行,是不是借用第三方工具并不重要。

TOP

数据列累加问题很容易实现。
如果用批处理,要考虑批处理能够计算的极值。
如果允许用第三方工具,根据CU前人讨论的结果,gawk应该是最快的。
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

返回列表