![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-10-01 21:16 |
共 47,813 主题排行 / 349,918 发帖 / 今日 0 篇 / 48,279 会员排行 |
| DOS批处理 & 脚本技术(批处理室) » 统计文本文件的字符个数 |
| 可打印版本 4,220 / 31 |
| 第1楼 pusofalse | 发表于 2008-04-24 21:59 |
| 银牌会员 发帖 646 积分 1,604 | |
|
统计文本文件的字符个数 @echo off&setlocal enabledelayedexpansion
set/a n=0,m=0,z=0,x=0 if not "%1"=="" (set file=%1) else set /p file=把要统计的文件拖到此处: if not exist %file% echo 找不到文件&exit/b echo 正在计算,请稍候。。。 for /f "tokens=*" %%a in ('findstr /n .* %file%') do ( set str=%%a set str=!str:*:=! call :lp ) set /a n=%n%+%x%+%z% echo %file%中有%n%个字符,[Space]有%m%个。 pause&goto :eof :lp if defined str ( set var=!str:~0,1! if not "!var!"=="" set /a n+=1 if "!var!"=="!" set /a z+=1 if "!var!"=="^^" set /a x+=1 if "!var!"==" " set /a m+=1 set str=!str:~1! goto lp ) 虽然对特殊字符稍微做了一点处理,但同样不适用于P。。。 |
|
| 第2楼 slore | 发表于 2008-04-24 22:28 |
| 铂金会员 发帖 2,478 积分 5,212 | |
|
VBS的len函数很好用嗬。
|
|
| 第3楼 slore | 发表于 2008-04-24 22:28 |
| 铂金会员 发帖 2,478 积分 5,212 | |
|
如果纯e文的话,直接看大小嗬。
|
|
| 第4楼 bat-zw | 发表于 2008-04-24 22:42 |
| 金牌会员 发帖 1,276 积分 3,105 | |
|
这种学习方法值得提倡: 别的不说,楼主举一返三的精神是可贵的,也是一条提高的捷径,加油!!!
|
|
| 第5楼 pusofalse | 发表于 2008-04-24 23:19 |
| 银牌会员 发帖 646 积分 1,604 | |
|
谢谢楼上几位。。。VBS不会用。。。只会用一个msgbox - -|||
|
|
| 第6楼 bat-zw | 发表于 2008-04-25 01:27 |
| 金牌会员 发帖 1,276 积分 3,105 | |
|
为支持楼主也来一个: 特殊字符太难处理了,故没考虑:
[ Last edited by zw19750516 on 2008-4-25 at 01:37 AM ] |
|
| 第7楼 pusofalse | 发表于 2008-04-25 02:31 |
| 银牌会员 发帖 646 积分 1,604 | |
Originally posted by zw19750516 at 2008-4-25 01:27 AM: |
|
| 第8楼 bjsh | 发表于 2008-04-25 14:19 |
| 银牌会员 发帖 621 积分 2,000 | |
|
这一段倒是 不怕特殊字符。。 它是打印出每一行的字符数, 并没有进行
整体统计。。 当然你也可以用下面这个进行 整体统计, 但是这个对稍大点的文件就会有问题。。 导致setlocal 递归层过大。。 这里有命令行固有的缺陷 假如你想完完整整的(包括特殊字符)获取到, 那在set "var=%%a" 之前 一定不要打开 变量延迟, 不然!号和^会被吃掉。。 但这样也造成另一个问题: 假如这有最开始的一个环境变量表 |----------------------------------------------| | | | | | | ------------------------------------------------- 执行set "var=%%a"后变为: 假如var=1:abcd |----------------------------------------------| | | | var=1:abcd | | | ------------------------------------------------- 当你执行 setlocal 时, 会产生一个新表, 实际上是copy调用setlocal的那张表, 但是以后对环境变量的修改只会作用于新表,当执行 endlocal 时,会恢复到原来 那张表。 执行setlocal 后产生新表 |----------------------------------------------| | | | var=1:abcd | | | ------------------------------------------------- 执行 set var=!var:*:=! call :Loop 后这张新表变为: |----------------------------------------------| | | | var=abcd | | n=4 | ------------------------------------------------- 当执行endlocal时 环境变量的表 恢复到最初 即 |----------------------------------------------| | | | var=1:abcd | | | ------------------------------------------------- 可见 n 没有了。。 这也是为什么第一个代码 只统计每一行 而没有 统计全部的原因 因为每一次统计 时 执行 set /a n+=1 n的初始值都为零。 可能有人会有这样的疑问: 不执行endlocal行不行。。 答案是也行, 就比如第二段代码 但是要记住: 一定要在 set "var=%%a"之前关闭掉 变量延迟 这样会不断的递归产生 环境表。 对于小文件还尚可。。 文件行数稍大便会 导致setlocal递归层数过大 所谓cmd固有缺陷: cmd中实际上没有真正变量的概念 而是以环境变量来模拟或者说是代替的 对于这种方式有个问题 因为 父shell 可以传递环境变量 给子shell 而 子shell 无法 改变父 shell中的环境变量 所以在setlocal后对原“变量”的修改 无法传递回来。。 除非 将其存入磁盘。。 ================================ 所以 更可行的方式 是 利用第一个代码, 将各行的字符数写入临时文件 最后再从 临时文件中 读取并计算和。。。 缺点自然就是 产生临时文件。 ====================================== 受10楼兄弟的启发, 下面这个代码即可统计 不必产生临时文件, 而且也 发现了 把变量传递回来的好办法。 很聪明的一个办法。。。 主要在两点。。 1) 让 set /a total+=n 脱离 循环的区域 但又被执行到 原因是为了避免 在for中 没执行前的命令行扫描 即将 n 替换掉 2)endlocal&&set /a total+=n 很聪明的做法 也是传递回来的根本原因所在 因为在一行。。。 所以 命令行 会对整体进行扫描 因为扫描时还没有执行endlocal, n 的值仍然存在, 而对其的替换恰发生在此时 扫描完毕后 真正执行时,endlocal 后 还原回原来的环境变量表, 但是 set /a total+=n 在扫描后 n 被替换为一个确定的值, 因此n的值通过total 被传递回原来的环境表量表 刚好利用了 扫描替换变量和执行的时间差。。 注意一定要在同一行, endlocal set /a total+=n 分开写, 第二行则永远是零了。。。 [ Last edited by bjsh on 2008-4-26 at 11:26 AM ] |
|
| 第9楼 plp626 | 发表于 2008-04-25 14:38 |
| 银牌会员 发帖 1,020 积分 2,278 | |
|
要想函数用的好,setlocal 必须掌握!
|
|
| 第10楼 26933062 | 发表于 2008-04-25 18:05 |
| 银牌会员 发帖 879 积分 2,268 | |
|
8 楼版主的代码稍作修改即可达到效果:
[ Last edited by 26933062 on 2008-4-25 at 06:06 PM ] |
|
| 第11楼 bat-zw | 发表于 2008-04-25 21:41 |
| 金牌会员 发帖 1,276 积分 3,105 | |
|
顶!!! bjsh版主描述的太清楚了,确实特殊字符太难处理了,尤其是在字符截取和开启变量延迟时,这里还真是cmd的瓶颈啊。
|
|
| 第12楼 bat-zw | 发表于 2008-04-25 21:44 |
| 金牌会员 发帖 1,276 积分 3,105 | |
Originally posted by 26933062 at 2008-4-25 18:05: |
|
| 第13楼 pusofalse | 发表于 2008-04-25 21:55 |
| 银牌会员 发帖 646 积分 1,604 | |
|
以下代码转自lxmxn @echo off&setlocal enabledelayedexpansion
set /p file= for /f "delims=: tokens=1*" %%a in ('findstr /n .* %file%') do ( set n=&set str=%%b if not "!str!"=="" ( for %%i in (!str!) do set /a n+=1 echo/line:%%a !n!个字符串。。。【!str!】 ) else ( echo/line:%%a 0个字符串。。。 ) ) pause>nul&cls&goto :eof 只要有特殊字符,字符串个数也会计算错误,难道没有好的方法了吗~ |
|
| 第14楼 bat-zw | 发表于 2008-04-25 21:58 |
| 金牌会员 发帖 1,276 积分 3,105 | |
|
暂时想不到啊,其实我一直在思考这个问题,也一直找不到好的解决方案。
|
|
| 第15楼 bjsh | 发表于 2008-04-25 22:06 |
| 银牌会员 发帖 621 积分 2,000 | |
|
10 楼的代码很聪明 真的很聪明!
|
|
| 1 2 3 下一页 |
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |