找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
楼主: 慕夜蓝化

[文本处理] [已解决]批处理如何查找出文本中字符数最多的行/字符串长度最长的行

[复制链接]
发表于 2015-3-9 20:20:17 | 显示全部楼层
本帖最后由 CrLf 于 2015-3-9 20:21 编辑

回复 15# cobat


环境变量的本质是一张连续的变量表,比如
  1. set 变量1=变量内容1
  2. set 变量2=变量内容2
复制代码
假设当前环境下只有这两个变量的话,那么整张表在内存中的表现是:
  1. 变量1=变量内容1(null)变量2=变量内容2(null)(null)
复制代码
(null) 表示 00 字符,连续两个 (null) 表示变量表结束
读写变量的时候就是不停检索等号前有没有相同的名称,匹配的话就输出后面的内容直到 (null)
这个逻辑在 xp 下很严格,win7 环境中则有诡异的表现,应该是个 bug

setlocal 其实是在当前变量表的基础上复制一张变量表,所有改动都在“分身”上进行,这张新的变量表直到文件末尾或碰到 endlocal 才会销毁
变量表最多同时存在 32 张,每次 call 之后可单独计算

提到变量,这里有几个旧帖值得一看,作者都是牛逼人物...
qzwqzw: [讨论]环境变量的存储(5-18更新)
caruko:批处理变量表机制的猜测及测试
plp626:扩展ASCII码字符集0x00~0xff 批处理获取函数
记得 demon 也有提到过变量,现在找不到帖子了

评分

参与人数 1技术 +1 收起 理由
cobat + 1 乐于助人

查看全部评分

发表于 2015-3-9 20:25:10 | 显示全部楼层
回复 16# CrLf


   谢谢,先收藏了慢慢看.
发表于 2015-3-10 09:06:27 | 显示全部楼层
用 findstr /N /O ,读取字符偏移量,然后取出最大的行,无需计算字符长度。
发表于 2015-3-10 09:58:18 | 显示全部楼层
  1. @echo off&setlocal enabledelayedexpansion
  2. set /a offset=0,len=0,max=0
  3. for /f "tokens=1,2* delims=:" %%a in ('findstr /N /O .*  文本.txt') do (
  4.         set /a len=%%b-offset,offset=%%b
  5.         set "#%%a=%%c"
  6.         if !len! geq !max! (
  7.                 set /a max=len,row=%%a-1
  8.                 for %%K in (!max!) do set "_%%K=!_%%K!,!row!"
  9.         )
  10. )
  11. for %%a in (!_%max%!) do echo,行数【%%a】,长度【%max%】,内容【!#%%a!】
  12. pause
复制代码

评分

参与人数 2技术 +2 收起 理由
慕夜蓝化 + 1
cobat + 1 乐于助人

查看全部评分

发表于 2015-3-10 16:03:32 | 显示全部楼层
回复 19# caruko


    为什么会这么快,不是说findstr很慢?
发表于 2015-3-10 16:57:40 | 显示全部楼层
回复 20# cobat


    外部命令的特点是启动慢,执行快…
    话说你在15楼问的是什么意思哦
发表于 2015-3-10 17:13:01 | 显示全部楼层
回复 21# CrLf

是不是计算单个字符串长度用strlen,文本里就用findstr /o
在看两个讲批处理效率的帖子,不能在for里用call
setlocal没搞懂在子批处理里面是什么情况呢?
发表于 2015-3-10 18:49:46 | 显示全部楼层
本帖最后由 CrLf 于 2015-3-10 18:57 编辑

回复 22# cobat


    call 执行起来很慢,其实还是看需求,一般情况下低效率的脚本都是让人难以容忍的
    每次使用外部命令都得尽可能压榨它的潜力,启动慢的命令都要避免频繁调用,但如果调用次数不多就没关系
http://www.bathome.net/viewthread.php?tid=15011
发表于 2015-3-10 18:50:39 | 显示全部楼层
本帖最后由 apang 于 2015-3-10 18:52 编辑

findstr /o 得到的是字节数,不是字符数,难道是我记错了?好像文本最后还需要两个回车换行,否则最后一行获取不到

评分

参与人数 1技术 +1 收起 理由
cobat + 1 乐于助人

查看全部评分

发表于 2015-3-12 11:08:36 | 显示全部楼层
回复 20# cobat


    因为代码只执行了 一次 findstr ,慢也超不过半秒。

     而其它代码效率高,足够把效率追回来。
 楼主| 发表于 2015-3-12 11:33:02 | 显示全部楼层
回复 23# CrLf

call 真的很慢....我之前写的时候经常用它,不过现在也在学着避免使用call
改用for 之类的来替换。
发表于 2015-3-12 16:18:53 | 显示全部楼层
回复 24# apang


    的确是,这个忘记了。 不过不影响长度判断。 最后一行可以用%%~ta -2 (减去回车换行字节) 再减去最后一行的offset 。
发表于 2015-3-12 20:05:37 | 显示全部楼层
回复 27# caruko


    嗯嗯,%%~za

话说本帖浏览超过1000次,火火的
发表于 2015-3-13 00:56:29 | 显示全部楼层
回复 27# caruko


    findstr /o 有个陷阱,对同时存在 \r\n 和 \n 两种换行方式的文本比较难以区分
发表于 2015-3-14 07:14:47 | 显示全部楼层
本帖最后由 无名小卒 于 2015-3-14 07:40 编辑

@echo off&setlocal enabledelayedexpansion
set ling=0
:⊙﹏⊙ 新人 大神勿喷
md lingmou
for /f "delims=" %%i in (堕落血天使.txt) do (
    set /a ling+=1
    echo %%i
)>.\lingmou\ling!!.txt
cd .\lingmou
for %%i in ('dir /d /o:-s ') do (
set "xy=%%i"
set xie=%%zi
set /a h+=1
if !h!=1 set  " t=%%zi"
if !xie!==!t! call :tong !xy!
)
exit
:tong
type %1
type
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 07:04 , Processed in 0.022332 second(s), 7 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表