标题: [文本处理] 【练习】批处理显示文本中8字节的行 [打印本页]
作者: 随风 时间: 2009-6-10 17:19 标题: 【练习】批处理显示文本中8字节的行
在百度贴吧看到一题,出给大家练练手。
那儿有一仙说他们老大不加思索就作出来了,(本人足足想了10分钟才有完整思路)实在对这位老大佩服的很,可惜未见到代码 (^_^)
题:
要求显示a.txt中8字节的行,注意有特殊字符 ^%&<!>等。
增加要求为:不创建临时文件,不使用第三方工具。
注意:说的是字节而不是字符,需考虑到多种情况,比如冒号、分号开头的行。。。
.
作者: zqz0012005 时间: 2009-6-10 17:37
我首先想到的思路是:for /f 解析 findstr /o 做减法
作者: batman 时间: 2009-6-10 17:45
小水一个:不创建临时文件就确实加大了难度了,呵呵,看看大家的思路吧。。。
作者: netbenton 时间: 2009-6-10 19:02
抛砖引玉
- @echo off
- for /f "delims=" %%a in (%~0) do (
- set str=%%a
- setlocal enabledelayedexpansion
- if "!str:~8!" equ "" (
- for /l %%b in (0,1,7) do (
- if "!str:~%%b,1!" neq "" (
- if "!str:~%%b,1!0" gtr "z" (set/a len+=2) else (set/a len+=1)
- rem ^ 这个字符用小于最小全角字符的即可,这知是不是z
- )
- )
- )
- if !len! equ 8 echo;!str!
-
- endlocal
-
- )
- pause
- rem 后面的是例子
- :2345678
- ::批处理
- ::!!!!!!
- ::^"!!|>
- ::物><!%
- :23456789
- ::批处理1
- ::!!!!!!1
- ::^"!!|>1
- ::物><!%1
复制代码
作者: 随风 时间: 2009-6-10 19:12 标题: 回复 4楼 的帖子
先忽略8个字符以上的行,再逐字判断,不错,但若需显示的行不是8字节而是更大点的数,效率会同时降低,且未考虑分号开头的行和含全角空格的行。
先加5分,后面的继续。。。
[ 本帖最后由 随风 于 2009-6-10 19:19 编辑 ]
作者: netbenton 时间: 2009-6-10 19:28
解决分号问题了
- @echo off
- for /f "tokens=* delims=;" %%a in ('findstr /n .* %0') do (
- set str=%%a
- setlocal enabledelayedexpansion
- set "str=!str:*:=!"
- if "!str:~8!" equ "" (
- for /l %%b in (0,1,7) do (
- if "!str:~%%b,1!" neq "" (
- if "!str:~%%b,1!0" gtr "z" (set/a len+=2) else (set/a len+=1)
- rem ^ 这个字符用小于最小全角字符的即可,这知是不是z
- )
- )
- )
- if !len! equ 8 echo;!str!
-
- endlocal
-
- )
- pause
- rem 后面的是例子
- :2345678
- ::批处理
- ::!!!!!!
- ::^"!!|>
- ::物><!%
- :23456789
- ::批处理1
- ::!!!!!!1
- ::^"!!|>1
- ::物><!%1
- ;ddddddd
复制代码
作者: 随风 时间: 2009-6-10 19:41 标题: 回复 6楼 的帖子
全角空格呢? (^_^)
作者: zqz0012005 时间: 2009-6-10 19:51
考虑到所有特殊字符的情况后,2楼说的方法实现起来还真有点麻烦。
先来个代码简单但效率超低的方法- @echo off
- set var2=.
- for /f "usebackq delims=" %%a in ("%~f0") do (
- set var=%%a
- set var|findstr /o ".*"|findstr /b "14:" >nul && (
- setlocal enabledelayedExpansion
- echo !var!
- endlocal
- )
- )
- pause&exit/b
-
- :2345678
- ^%; <!"
- 上面是全角空格
复制代码
作者: 随风 时间: 2009-6-10 19:56 标题: 回复 8楼 的帖子
效率是够低的,也每考虑分号开头的行 (^_^)
作者: netbenton 时间: 2009-6-10 20:25
高效的,可处理绝大部分字符
- @echo off
- for /f "tokens=*" %%a in ('^(type %0^&echo.^)^|findstr /o .*') do (
- set str=%%a
- setlocal enabledelayedexpansion
- for /f "delims=:" %%b in ("!str!") do (
- set/a len=%%b-up-2
- if !len! equ 8 echo !ech!
- set "ech="
- for %%c in ("!str:*:=!") do (
- endlocal&set up=%%b&set ech=%%~c
- ))
-
- )
- pause
- rem 后面的是例子
- :2345678
- ::批处理
- ::!!!!!!
- ::^"!!|>
- ::物><!%
- :23456789
- ::批处理1
- ::!!!!!!1
- ::^"!!|>1
- ::物><!%1
- ;ddddddd
复制代码
作者: zqz0012005 时间: 2009-6-10 20:39 标题: 回复 8楼 的帖子
2楼的方法其实不麻烦,开始没想清楚,变量还是可以保留的- @echo off
- for /f "tokens=1* delims=:" %%a in ('findstr /n /o .* "%~f0"') do (
- for /f "delims=:" %%i in ("%%b") do set m=%%i
- set /a x=m-n
- setlocal enabledelayedExpansion
- if !x!==10 echo !var:*:=!
- endlocal
- set /a n=m
- set var=%%b
- )
- pause&exit/b
-
- ;2345678
- ^%; <!"
- 上面是全角空格
复制代码
作者: zqz0012005 时间: 2009-6-10 20:43
晕,findstr /n 写习惯了,%%a根本没用到~~
for /f "delims=" %%a in ('findstr /o .* "%~f0"') do
方法都一样,被netbenton兄抢先了,而且考虑到了最后一行没有回车的情况。
"tokens=*"改成"delims="就兼容所有字符了。
可以用more "%~f0"|findstr /o .*更简洁点,more会在文本内容后面加额外的回车。
[ 本帖最后由 zqz0012005 于 2009-6-10 20:57 编辑 ]
作者: netbenton 时间: 2009-6-10 21:07
re zqz0012005
我正找了半天,怎么解最后一行不是空格的问题呢!
原来用more可以自动加空行呀,太好了!
完美代码如下:
- @echo off
- for /f "tokens=*" %%a in ('^(more %0 ^&echo aa^)^|findstr /o .*') do (
- set str=%%a
- setlocal enabledelayedexpansion
- for /f "delims=:" %%b in ("!str!") do (
- set/a len=%%b-up-2
- if !len! equ 8 echo !ech:*:=!
- endlocal&set/a up=%%b
- )
- set ech=%%a
- )
- pause
- rem 后面的是例子
- :2345678
- ::批处理
- ::!!!!!!
- ::^"!!|>
- ::物><!%
- :23456789
- ::批处理1
- ::!!!!!!1
- ::^"!!|>1
- ::物><!%1
- ;ddddddd
- ^%; <!"
复制代码
作者: 随风 时间: 2009-6-10 21:14 标题: 回复 12楼 的帖子
zqz 真是一语点醒梦中人,代码早以写好,就是解决不了最后一行没有回车的问题。老是用type
最终大家的思路都到一起来了 (^_^)
代码如下:- @echo off&set /a h=0
- for /f "delims=" %%a in ('^(more %~s0^&echo.^)^|findstr /o .*') do (
- for /f "delims=:" %%i in ("%%a") do set /a n=%%i-2-h,h=%%i
- setlocal enabledelayedexpansion
- if !N! equ 8 echo;【!var:*:=!】
- endlocal
- set "var=%%a"
- )
- pause&exit
-
- 下面是分号开头的行
- ;1234567
- 下面是8个空格
-
- 下面是冒号开头的行
- ::::::::
- 下面是特殊字符的行
- %^&*<">!
- 下面是含全角空格的行
- 78
- 下面是全角半角混合的行
- 壹23肆78
- 下面是纯半角字符的行
- 12345678
复制代码
作者: zqz0012005 时间: 2009-6-10 21:21
忘了,最后还要自己加一行,以应付最后一行也是8个字节的情况。
作者: tireless 时间: 2009-6-10 22:10
用 z 区分不了双字节与单字节字符。
全角字符占 2 个字节,而全角的 a会小于半角的 b
作者: terse 时间: 2009-6-10 22:35
还真没想到 more 会自己加行 最后行一直困人哦 少个FOR 可行吗- @echo off
- for /f "tokens=1* delims=:" %%i in ('"(more 1.txt&echo aa)|findstr /o ".*""') do (
- set/a n=%%i-m-2
- setlocal enabledelayedexpansion
- if !n! equ 8 echo !var!
- endlocal&set var=%%j&set/a m=%%i
- )
- pause
复制代码
作者: 随风 时间: 2009-6-10 22:52 标题: 回复 17楼 的帖子
这样会忽略冒号开头的行吧。
作者: slore 时间: 2009-6-11 01:14
1234567半
不能完全8字节分吧...汉字难道要...
作者: qq106942397 时间: 2009-6-11 23:28
测试一吓我的笨方法吧~~
@echo off
for /f "tokens=* delims=國" %%a in (总和数.txt) do (
set "q=%%a"
echo %%a>t.txt<nul
echo.>>t.txt
for /f "skip=1 tokens=1* delims=:" %%b in ('findstr /o .* t.txt') do (
if %%b==10 call set/p"=%%q%%">>总和数2.txt<nul&echo.>>总和数2.txt
)
)
del t.txt
pause
作者: qq106942397 时间: 2009-6-11 23:30
对文本大的速度不行~~现在还在想另的方法~~在群里还谈~~你又不上群里聊~~~
作者: qq106942397 时间: 2009-6-14 21:16
楼上骗子点击呀~~~
用EXE文件这也算吗???
作者: 随风 时间: 2009-6-14 21:23 标题: 回复 23楼 的帖子
看22楼的意思应该是自己编写的exe文件,这不应该说算,应该说很牛啊。
作者: keen 时间: 2009-6-14 23:05
- @echo off
- for /f "eol= delims=" %%i in ('type a.txt') do (set "str=%%i"
- for /f "skip=1 delims=:" %%a in ('^(echo "%%i"^&echo;^)^|findstr /o .*') do (
- set /a num=%%a-5
- setlocal enabledelayedexpansion
- if !num! equ 8 echo;!str!
- endlocal
- )
- )
- pause
复制代码
作者: 随风 时间: 2009-6-23 15:43
狂汗,居然如此简单。。。
:- @echo off
- (more a.txt&echo.)|findstr /x ........
- pause
复制代码
作者: zqz0012005 时间: 2009-6-23 18:05
后面的“echo.”是不必要的,more也是不必要的,直接用type也行,此时不存在最后行问题。
findstr 的正则还真是古怪。下面是javascript的正则:- mshta "javascript:alert( '12345678\r\n一二三四'.match(/^........$/gim) ); alert( '12345678\r\n一二三四'.match(/^....$/gim) );close();"
复制代码
看来 findstr 问题不少。除了以前cn-dos的willsort总结的,前不久又有人发现了一个:http://bbs.verybat.org/thread-18013-1-2.html
作者: zhouyongjun 时间: 2009-6-23 18:09 标题: 回复 27楼 的帖子
确实牛,但是有疑惑了
. 通配符: 任何字符(findstr的帮助)
我在百度上搜索,字符时有别于字节的:
字符指一个字母或一个字或一个标点或一个符号,不一定几个字节
显然这里的点号是匹配字节了,我用上面的代码测试了,一个汉字要两点才能匹配
有点糊涂了。。。
作者: zqz0012005 时间: 2009-6-23 19:43
findstr /x strings filename,等同于 findstr "^strings$" filename,也等同于 findstr /be "strings" filename
这样的写法有最后行问题(最后行没有回车的情况)。
type filename | findstr /x strings
这样写没有上面的问题。
作者: zqz0012005 时间: 2009-8-14 15:35 标题: 回复 13、14楼 的帖子
(more "%~f0"&echo.)|findstr /o .*
这样会多出额外的空格。
要再加一行,其实多加一个more就行了:
more "%~f0"|more|findstr /o .*
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |