标题: 【练习-050】批处理超越for命令tokens极限分割字符串 [打印本页]
作者: batman 时间: 2009-8-12 10:50 标题: 【练习-050】批处理超越for命令tokens极限分割字符串
可能有的新手还不知道在for循环中tokens(列)的极限数是31,
而且将同一行中整整31列内容来分行显示也是极为麻烦的,一般不是用
echo %%a&echo %%b...&echo %%z...的这样形式就是用call :lp+shi
ft移位来完成的。
那么能不能突破这一tokens极限数?又能不能很方便地将一行内
数十列内容分行显示出来?这就是我们今天提出的问题了。
已知一超长字串符:d_q 973-c_j 314+y_d 356+i_p 638-u_m 2
04+w_a 588+j_c 829-p_t 599+j_v 803-p_y 92-r_h 677+h_i 341+h_
q 705-r_f 601-m_s 822+q_q 17-w_y 720+s_d 325-d_n 559-l_s 109
+l_v 160-x_b 232-u_r 282-v_l 521+p_o 403-x_n 613+t_x 185-g_v
678+z_n 753+j_k 779-o_f 283-h_w 390-z_o 772-w_v 252-a_e 51-
m_t 945-k_q 444-r_m 233-p_w 744+k_k 136-w_k 131-s_o 163+k_i
733+w_c 733+g_l 42+o_i 515+x_h 130-n_b 200+i_u 25+z_i 730,现
在要求将这一字串符以+-符为分隔符分行显示出来,每行的显示形式应
为“字母_字母 数值”,如倒数第四行的内容为x_h 130。
本题满分10分,视情况加分。
注:请先将此题留给新人们思考(此贴是用批进行自动排版)。
[ 本帖最后由 batman 于 2009-8-12 11:06 编辑 ]
作者: terse 时间: 2009-8-12 12:18
我想一个替换 一个移位
应该是替换的效率高点吧
作者: Seter 时间: 2009-8-12 12:19
咱只擅长C啊..这个用C的思路写出来的...额额..
于是这个是很兀余+很没可读性+很缺乏创意+很浪费资源+最后一个数据不晓得为什么会过几秒再跳出来的新手代码....希望大大们指正咯~
- @echo off&setlocal enabledelayedexpansion
- set /p f=<t.txt
- set num=0
- set n=
- :loop
- if "!f:~%num%,1!"=="" goto init
- set /a num=num+1
- goto loop
- :init
- set i=0
- :next
- if "%i%"=="%num%" echo %f%&pause>nul&exit
- if "!f:~%i%,1!"=="+" goto sum
- if "!f:~%i%,1!"=="-" goto sum
- set /a i=i+1
- goto next
- :sum
- echo !f:~0,%i%!
- set /a end=%num%-%i%-1
- set /a i=i+1
- set f=!f:~%i%,%end%!
- set i=0
- goto next
复制代码
[ 本帖最后由 Seter 于 2009-8-12 12:27 编辑 ]
作者: batman 时间: 2009-8-12 12:29 标题: 回复 3楼 的帖子
楼上代码最大的问题在于效率上,使用逐字符不是解本题的上上之法。。。
作者: 523066680 时间: 2009-8-12 12:45
把上面整条字符串复制在text.txt
d_q 973-c_j 314+y_d 356+i_p 638-u_m 204+w_a 588+j_c 829-p_t 599+j_v 803-p_y 92-r_h 677+h_i 341+h_q 705-r_f 601-m_s 822+q_q17-w_y 720+s_d 325-d_n 559-l_s 109+l_v 160-x_b 232-u_r 282-v_l 521+p_o 403-x_n 613+t_x 185-g_v678+z_n 753+j_k 779-o_f 283-h_w 390-z_o 772-w_v 252-a_e 51-m_t 945-k_q 444-r_m 233-p_w 744+k_k 136-w_k 131-s_o 163+k_i 733+w_c 733+g_l 42+o_i 515+x_h 130-n_b 200+i_u 25+z_i 730
- @echo off
- err>temp.x 2>nul
- for /f "tokens=*" %%a in (text.txt) do (set a="%%a")
- set a=%a:-=" "%
- set a=%a:+=" "%
- for %%A in (%a%) do echo %%~A>>temp.x
- type temp.x
- pause
复制代码
[ 本帖最后由 523066680 于 2009-8-12 12:46 编辑 ]
作者: terse 时间: 2009-8-12 13:34
523066680兄的代码 是假设代码只有一行吧 如是这样那就不要FOR了 直接SET 怎么样 set /pa=<text.txt
作者: 523066680 时间: 2009-8-12 13:55
哈 被你发现拉~ 没办法 ……在探究fsutil文本处理 头脑乱了……
话说pusofalse的分好好拿……
作者: Batcher 时间: 2009-8-12 17:55
纯路过复制代码
作者: batman 时间: 2009-8-12 19:43 标题: 回复 8楼 的帖子
路过的就不加分了,再说你用第三方,与出题的初衷不符。。。
作者: netbenton 时间: 2009-8-12 19:49
set /pa=<text.txt
只能读取1024字节
而for /f ...
最多可以读取8K字节
针对此题不会有问题,要是讲通用性,还是用for好
作者: 523066680 时间: 2009-8-12 20:46
netbenton回归平民拉 ~ 我也要……
话说 你研究的真仔细。
作者: 基拉freedom 时间: 2009-8-12 22:23
谁有我简洁 连for也省了..............
不过爆出一个我想不通的问题 问什么第一个会到最后去呢??
保存那个字符串为1.txt- @echo off
- set /p f=<1.txt
- set f=%f:-=+%
- set f=%f:+=&echo %
- set f=echo %f%
- %f%
- pause
复制代码
作者: netbenton 时间: 2009-8-12 23:05
楼上的有创意哦!
在%f%前面加个echo 吧
echo %f%
第一个跑到后面的问题似乎不存在呀!
作者: defanive 时间: 2009-8-12 23:59
5L和12L的代码亮点。。。
作者: batman 时间: 2009-8-13 08:45
还有种无限tokens的办法- @echo off
- set "str=d_q 973-c_j 314+y_d 356+i_p 638-u_m 204+w_a 588+j_c 829-p_t 599+j_v 803-p_y 92-r_h 677+h_i 341+h_q 705-r_f 601-m_s 822+q_q17-w_y 720+s_d 325-d_n 559-l_s 109+l_v 160-x_b 232-u_r 282-v_l 521+p_o 403-x_n 613+t_x 185-g_v678+z_n 753+j_k 779-o_f 283-h_w 390-z_o 772-w_v 252-a_e 51-m_t 945-k_q 444-r_m 233-p_w 744+k_k 136-w_k 131-s_o 163+k_i 733+w_c 733+g_l 42+o_i 515+x_h 130-n_b 200+i_u 25+z_i 730"
- :lp
- for /f "tokens=1* delims=+-" %%a in ("%str%") do (
- echo %%a
- if "%%b" neq "" set "str=%%b"&goto lp
- )
- pause>nul
复制代码
作者: Seter 时间: 2009-8-13 09:56
昏...我的思路和BATMAN一样的...居然没想到用for的1*....
作者: Lumiere 时间: 2009-8-14 21:22 标题: 回复 12楼 的帖子
第一个跑后面是因为你的代码有个小错误,显示结果只不过是乱打正着。批处理预处理的时候你的f定义"set f=%f:+=&echo %" 被解释为“set f=d_q 973 & echo c_j 314........”所以你的显示结果其实是从这一句就开始了,而不是最后一个命令%f%。最后一个%f%其实显示的就是第一节。
整个代码如果要完美应该改成- @echo off
- set /p f=<1.txt
- set f=%f:-=+%
- set f=%f:+=^&echo %
- echo %f%
- pause
复制代码
这样的话&可以在最后一个echo的时候经过预处理解释成连接符,而不会在第三句的时候就被解释成连接符。
作者: Lumiere 时间: 2009-8-14 21:24 标题: 回复 15楼 的帖子
我首先想到的就是这个方法,以前替换文本中的等号=的时候用过。呵呵,看样子出差三天论坛上我错过了不少好戏啊……
作者: rat 时间: 2009-8-18 17:56 标题: 把+-替换成回车
- @echo off & setlocal
- set s=d_q 973-c_j 314+y_d 356+i_p 638-u_m 204+w_a 588+j_c 829-p_t 599+j_v 803-p_y 92-r_h 677+h_i 341+h_q 705-r_f 601-m_s 822+q_q 17-w_y 720+s_d 325-d_n 559-l_s 109+l_v 160-x_b 232-u_r 282-v_l 521+p_o 403-x_n 613+t_x 185-g_v 678+z_n 753+j_k 779-o_f 283-h_w 390-z_o 772-w_v 252-a_e 51-m_t 945-k_q 444-r_m 233-p_w 744+k_k 136-w_k 131-s_o 163+k_i 733+w_c 733+g_l 42+o_i 515+x_h 130-n_b 200+i_u 25+z_i 730
- set s=%s:+=-%
- setlocal enabledelayedexpansion
- set s=!s:-=^
-
- !
- echo !s!
- endlocal
- pause>nul
复制代码
作者: FOR 时间: 2009-8-19 15:21
-
- @echo off
- set s=d_q 973-c_j 314+y_d 356+i_p 638-u_m 204+w_a 588+j_c 829-p_t 599+j_v 803-p_y 92-r_h
- 677+h_i 341+h_q 705-r_f 601-m_s 822+q_q 17-w_y 720+s_d 325-d_n 559-l_s 109+l_v 160-x_b 232-
- u_r 282-v_l 521+p_o 403-x_n 613+t_x 185-g_v 678+z_n 753+j_k 779-o_f 283-h_w 390-z_o 772-w_v
- 252-a_e 51-m_t 945-k_q 444-r_m 233-p_w 744+k_k 136-w_k 131-s_o 163+k_i 733+w_c 733+g_l
- 42+o_i 515+x_h 130-n_b 200+i_u 25+z_i 730
- set s=%s:+=-%
- set "s=echo %s:-=&echo;%"
- %s%
- pause
复制代码
作者: lt5 时间: 2012-4-9 05:39
本帖最后由 lt5 于 2012-4-11 05:10 编辑
- @echo off&setlocal enabledelayedexpansion
- set "f=d_q 973-c_j 314+y_d 356+i_p 638-u_m 204+w_a 588+j_c 829-p_t 599+j_v 803-p_y 92-r_h 677+h_i 341+h_q 705-r_f 601-m_s 822+q_q17-w_y 720+s_d 325-d_n 559-l_s 109+l_v 160-x_b 232-u_r 282-v_l 521+p_o 403-x_n 613+t_x 185-g_v678+z_n 753+j_k 779-o_f 283-h_w 390-z_o 772-w_v 252-a_e 51-m_t 945-k_q 444-r_m 233-p_w 744+k_k 136-w_k 131-s_o 163+k_i 733+w_c 733+g_l 42+o_i 515+x_h 130-n_b 200+i_u 25+z_i 730"
- set str=%f:+=-%
- set i=^
-
-
- for %%a in ("!i!") do (
- for /f "delims=" %%b in ("!str:-=%%~a!") do echo %%b
- )
- pause>nul
复制代码
上面的代码看似复杂,其实思路很简单,就是把分隔符替换成换行符,就像word一样。只用set的话无法把所有结果输入到文本文件,因为set默认是只取最后一行。
还有下面的虽然用了很多set,但为了能输入到文本里不得不用for循环,有没有不用for循环也能把结果输入到文本呢?- @echo off&setlocal enabledelayedexpansion
- set "str=d_q 973-c_j 314+y_d 356+i_p 638-u_m 204+w_a 588+j_c 829-p_t 599+j_v 803-p_y 92-r_h 677+h_i 341+h_q 705-r_f 601-m_s 822+q_q17-w_y 720+s_d 325-d_n 559-l_s 109+l_v 160-x_b 232-u_r 282-v_l 521+p_o 403-x_n 613+t_x 185-g_v678+z_n 753+j_k 779-o_f 283-h_w 390-z_o 772-w_v 252-a_e 51-m_t 945-k_q 444-r_m 233-p_w 744+k_k 136-w_k 131-s_o 163+k_i 733+w_c 733+g_l 42+o_i 515+x_h 130-n_b 200+i_u 25+z_i 730"
-
- set str=%str: =#%
- set str=%str:+= %
- set str=%str:-=;%
- for %%i in (%str%) do (set a=%%i
- echo !a:#= !)
- pause>nul
复制代码
作者: lt5 时间: 2012-4-12 12:19
本帖最后由 lt5 于 2012-4-12 12:26 编辑
- @echo off
- set "f=d_q 973-c_j 314+y_d 356+i_p 638-u_m 204+w_a 588+j_c 829-p_t 599+j_v 803-p_y 92-r_h 677+h_i 341+h_q 705-r_f 601-m_s 822+q_q17-w_y 720+s_d 325-d_n 559-l_s 109+l_v 160-x_b 232-u_r 282-v_l 521+p_o 403-x_n 613+t_x 185-g_v678+z_n 753+j_k 779-o_f 283-h_w 390-z_o 772-w_v 252-a_e 51-m_t 945-k_q 444-r_m 233-p_w 744+k_k 136-w_k 131-s_o 163+k_i 733+w_c 733+g_l 42+o_i 515+x_h 130-n_b 200+i_u 25+z_i 730"
- set f=+%f:-=+%
- set f=%f:+=>>test.x &echo %
- type test.x
- pause
复制代码
感觉还是batman的方法通用一些,后来的方法都是找到了这段文字的规律而已,所以代码显得很简洁。若是遇到其他文字这个方法可能就没用了
作者: zhyoli 时间: 2012-8-31 16:51
新手学习。。。收到!
作者: zhyoli 时间: 2012-8-31 18:13
都是高手,我来学习的。
作者: luonanyun 时间: 2012-9-14 20:30
回复 15# batman - set "str=d_q 973-c_j 314+y_d 356+i_p 638-u_m 204+w_a 588+j_c 829-p_t 599+j_v 803-p_y 92-r_h 677+h_i 341+h_q 705-r_f 601-m_s 822+q_q17-w_y 720+s_d 325-d_n 559-l_s 109+l_v 160-x_b 232-u_r 282-v_l 521+p_o 403-x_n 613+t_x 185-g_v678+z_n 753+j_k 779-o_f 283-h_w 390-z_o 772-w_v 252-a_e 51-m_t 945-k_q 444-r_m 233-p_w 744+k_k 136-w_k 131-s_o 163+k_i 733+w_c 733+g_l 42+o_i 515+x_h 130-n_b 200+i_u 25+z_i 730"
-
-
-
复制代码
刚才试了一下 好像这段不加引号也是可以的,加了和不加到底有什么区别啊? 求指教!!!
作者: jains521 时间: 2012-10-17 11:38
谁有我简洁 连for也省了..............
不过爆出一个我想不通的问题 问什么第一个会到最后去呢??
保存那 ...
基拉freedom 发表于 2009-8-12 22:23
为什么第一个会到最后一个去, 是因为第一个的前面没有+-符号,你用符号替换的时候. 第一个自然就 不会被处理了.所以.你就在最后加上了.echo %f%.
解决的方法就是在 在行首位置添加一个+-符号..
作者: a5321 时间: 2020-12-23 11:32
厉害啊 谢谢分享了
作者: qixiaobin0715 时间: 2021-11-16 09:33
出题出的好,答题答的妙!!!
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |