标题: 出题:整理文本 (新手老鸟都来试试)
[打印本页]
作者: 26933062
时间: 2008-7-13 19:51
标题: 出题:整理文本 (新手老鸟都来试试)
要求:把 a.txt 整理成按句号换行,
即:把没有句号的行和下行拼接,把有句号的行从句号处换行
注意:有可能连续几行都没有句号,也可能一行中有多个句号。
不用考虑特殊字符问题。
当然前提是不能把a.txt所有内容都拼接为一个变量。(因为变量的字符数是有限制的)
看谁的代码最简洁、高效、加分。。!
a.txt 内容如下:批处理文件(Batch File,简称 BAT文件)是一种在DOS
下最常用的可执行文件。它具有灵活的操纵性,可适应各
种复杂的计算机操作。所谓的批处理,就是按规定的顺序
自动执行若干个指定的DOS命令或程序。
即是把原来一个一个执行的命令汇总起来,成批的执行,而程序文件可
以移植到其它电脑中运行,因此可以大大节省命令反复输
入的繁琐。同时批处理文件还有一些编程的特点
。可以通过扩展参数来灵活的控制程序的执行,所以在日
常工作中非常实用。批处理。bat。cmd。尺有所短。寸有所长。
要求输出如下格式:批处理文件(Batch File,简称 BAT文件)是一种在DOS 下最常用的可执行文件。
它具有灵活的操纵性,可适应各种复杂的计算机操作。
所谓的批处理,就是按规定的顺序自动执行若干个指定的DOS命令或程序。
即是把一个一个执行的命令汇总起来成批的执行,而程序文件可以移植到其它电脑中运行,因此可以大大节省命令反复输入的繁琐。
同时批处理文件还有一些编程的特点。
可以通过扩展参数来灵活的控制程序的执行,所以在日常工作中非常实用。
批处理。
bat。
cmd。
尺有所短。
寸有所长。
总结一下:
答案众多,(2楼 14楼 17楼 19楼)
2楼采取逐字读取的办法,且可以处理大多数特殊字符,但效率太低。
14楼创建一个com文件、效率高的惊人。可惜我不懂、倒是长了见识。不过此题目的还是用纯p来解决。
17楼、19楼思路一样、代码略有不同,效率也不错、基本符合楼主要求。
[
Last edited by 26933062 on 2008-7-13 at 10:55 PM ]
作者: terse
时间: 2008-7-13 20:18
逐字读取
@echo off
for /f "delims=" %%i in ('findstr /n .* 1.txt') do (
set "str=%%i"
setlocal enabledelayedexpansion
set str=!str:*:=!
call :lp
endlocal
)
pause&exit
:lp
if defined str (
set /p= !str:~0,1!<nul
if "!str:~0,1!"=="。" echo.
set str=!str:~1!
goto lp
)
不考虑特殊字符 也可以简化下
@echo off&setlocal enabledelayedexpansion
for /f "delims=" %%i in (1.txt) do set str=%%i&call :lp
pause&exit
:lp
set /p= !str:~0,1!<nul
if "!str:~,1!"=="。" echo.
set str=!str:~1!
if defined str goto lp
[
Last edited by terse on 2008-7-13 at 08:23 PM ]
作者: 26933062
时间: 2008-7-13 20:21
逐字读取不失为一个办法,但效率就大打折扣了。
加 5 分。
作者: terse
时间: 2008-7-13 20:29
我想法把。换成echo. 可以吗
作者: slore
时间: 2008-7-13 20:37
标题: 要是用vbs就easy了……bat字符处理就看大家啦
即是把原来一个一个执行的命令汇总起来,成批的执行,而程序文件可
以移植到其它电脑中运行,因此可以大大节省命令反复输
入的繁琐。
即是把原来一个一个执行的命令汇总起来,成批的执行,而程序文件可以移植到其它电脑中
运行,因此可以大大节省命令反复输入的繁琐。
这个的断句又是如何决定的呢?
作者: quya
时间: 2008-7-13 20:58
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=" %%i in (text.txt) do (
set str=%%i
set/p=!str!<nul>>temp.txt)
for /f "delims=。" %%i in (temp.txt) do (echo %%i。&echo.)>>result.txt
可惜事与愿违, 最后的结果只有一行,高手帮我修改下。思路我认为是对的。
作者: HAT
时间: 2008-7-13 21:22
老土兄有没有研究过文本文件一行最多容纳多少个字符?超过这个极限,你的思路还正确吗?
作者: 26933062
时间: 2008-7-13 21:44
回 5 楼
即是把原来一个一个执行的命令汇总起来,成批的执行,而程序文件可以移植到其它电脑中运行,因此可以大大节省命令反复输入的繁琐。
这里中间没有句号,当然要算一句了。
作者: pusofalse
时间: 2008-7-13 21:52
这样可以吗。。。
@echo off&setlocal enabledelayedexpansion
for /f "delims=" %%a in (a.txt) do set str=!str!%%a
set str=%str:。=。^&echo.^&echo.%
echo %str%
pause>nul
不好意思,忘记详细看题了。。。
[
Last edited by pusofalse on 2008-7-13 at 09:56 PM ]
作者: slore
时间: 2008-7-13 21:54
那就是排版的问题?我就是不明白为什么在中字断开。。。
如果是vbs的话:replace "回车"为"空",replace "。"为 "。+回车"
作者: HAT
时间: 2008-7-13 21:54
标题: to 9楼
楼主不允许这样做啊,呵呵。
作者: HAT
时间: 2008-7-13 21:55
Unix下这样写应该可以成功,但Windows下就是不行,思考中。。。
sed "s/。/。\n/g" a.txt | sed "/。$/!s/\n//g"
作者: 26933062
时间: 2008-7-13 21:59
Quote: |
Originally posted by slore at 2008-7-13 21:54:
那就是排版的问题?我就是不明白为什么在中字断开。。。
如果是vbs的话:replace "回车"为"空",replace "。"为 "。+回车" |
|
并没有在“中”字断开,是论坛自动给它换行了。
所以我的样本中都是用空行代表换行的。这样说明白了么?
作者: qzwqzw
时间: 2008-7-13 22:01
换个思路
@echo off
chcp 437 >nul & graftabl 936 >nul
echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>sbs2.com
echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU WwX0GwUY Wv;ovBX2Gv0ExGIuht6>>sbs2.com
echo ?@}IKuNWpe~Fpe?FNHlF?wGMECIQqo{Ox{T?kPv@jeoSeIlRFD@{AyEKj@>>sbs2.com
echo iqe~1NeAyR?mHAG~BGRgB{~H?o~TsdgCYqe?HR~upkpBG?~slJBCyA?@xA>>sbs2.com
echo LZp{xq`Cs?H[C_vHDyB?Hos@QslFA@wQ~~x}viH}`LYNBGyA?@xAB?sUq`>>sbs2.com
echo LRy@PwtCYQEuFK@A~BxPtDss@fFqjVmzD@qBEOEenU?`eHHeBCMs?FExep>>sbs2.com
echo LHsPBGyA?@xAunjzA}EKNs@CA?wQpQpKLBHv?s`WJ`LRCYyIWMJaejCksl>>sbs2.com
echo H[GyFGhHBwHZjjHeoFasuFUJeHeB?OsQH[xeHCPvqFj@oq@eNc?~}Nu??O>>sbs2.com
echo ~oEwoAjBKs?Zp`LBzHQzyEFrAWAG{EFrAqAGYwHTECIQ{coKIsaCsf{Oe~>>sbs2.com
echo CK}Ayre~CNFA{rAyEKFACrA{EKGAjbA}eKGSjNMtQFtc{OAyDGFj?{FDGQ>>sbs2.com
echo KAjNVk_OCAx@e?f{o?CosI}1EGizhljJ~H1ZeG}JBA~rACBMDGjjDG@g0>>sbs2.com
sbs2.com>nul
sbs2.com 0 "$0d$0a" "" < a.txt > tmp.txt
sbs2.com 0 "。" "。$0d$0a$0d$0a" < tmp.txt > out.txt
del tmp.txt
del sbs2.com
作者: wxcute
时间: 2008-7-13 22:01
标题: ;回10楼
我觉得可能是记事本的BUG,有时用的好好的,关闭再打开时记事本就会出现中间断开的情况。
作者: slore
时间: 2008-7-13 22:10
Quote: |
Originally posted by 26933062 at 2008-7-13 21:59:
并没有在“中”字断开,是论坛自动给它换行了。
所以我的样本中都是用空行代表换行的。这样说明白了么? |
|
哦,那我也说了bat就看你show了……
vbs的就2句话我也说过了。。。如果要用vbs的话就自己把读写完成。。。
作者: lpk130
时间: 2008-7-13 22:11
@echo off&setlocal enabledelayedexpansion
for /f "tokens=*" %%a in (a.txt) do (
set "string=%%a"&set "str=%%a"
if "!str:~0,1!"=="。" echo 。&echo.
call :loop
if "!str:~-1!"=="。" echo 。&echo.
)
:loop
for /f "tokens=1,* delims=。" %%i in ("!string!") do (
set string=%%j
if defined string (
set/p=%%i。<nul
echo.&echo.
goto loop
) else (
set/p=%%i<nul
)
)
代码有点复杂
作者: 26933062
时间: 2008-7-13 22:16
14楼这个思路就换的远啊?
你太厉害了。。佩服,完全不懂。
还是看看纯bat的吧。。。。
作者: 26933062
时间: 2008-7-13 22:23
17楼的应该获满分了、可惜今天不能评分了,明天补上。
我的代码。 思路和17楼差不多。
@echo off&setlocal enabledelayedexpansion
for /f "delims=" %%i in (a.txt) do call :loop "%%i"
pause>nul
:loop
set "str=%~1"
for /f "tokens=1* delims=。" %%a in ("!var!%~1") do (
if "%%b"=="" (
if "!str:~-1!"=="。" (echo %%a。&echo.&set var=) else set "var=!var!%~1"
goto :eof
) else echo %%a。&echo.&set var=&call :loop "%%b"
)
goto :eof
作者: HAT
时间: 2008-7-13 22:24
虽然我看不懂14楼的代码,但我觉得并不满足楼主的要求。
从最后几行来看,应该是先把所有的0D0A(回车换行)替换为空,也就是把整个文本的内容和并成一行,再把句号替换成回车换行。这样做违背了楼主的本意。
不过代码本身还是值得我们学习,不知 qzwqzw 兄能否讲解一下?
作者: qzwqzw
时间: 2008-7-13 23:33
其实按照楼主的本意
本来使用change、sed等文本替换工具高效率、高兼容的
但不知什么原因
楼主一定要纯P的方案
只好折中了一下
使用ASCII Assembler生成一个文本替换工具
然后再用它替换源文本
至于它是否纯P
就不用讨论太多了
------------------------------------------------------------------
关于ASCII Assembler的细节搜索一下过去的帖子(按内容)
下面是sbs2的用法说明与源码
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Usage: sbs2.com NUMBER "STRING1" "STRING2" <infile >outfile
::
:: infile and outfile must be files (to allow random access), so in
:: NT/W2000/XP no pipe (program1 | sbst | program2) must be used!
:: infile and outfile must not be the same file!
::
:: Substitutes the NUMBER ocurrence of STRING1 in infile by
:: STRING2 and writes the result to outfile
::
:: You can include any character in STRING1/2 by using its
:: hex value (e.g. $0d for <CR> or $1a for EOF)
::
:: If NUMBER = 0 all STRING1 are substituted by STRING2
::
:: If an error is detected or nothing is substituted, erorrlevel=0
:: replace the original file only if errorlevel>=1 (=number of
:: substitutions).
::
:: Instead of the double quotes (") you can also use single quotes (')
:: with a different meaning for string2:
:: "string2" : normal substitution
:: 'string2" : before substitution the output file is rewinded
:: "string2' : after substitution the outputfile is closed
some examples:
-----------------------------------------------------
Substitutes the 2. occurrence of user by Susan
-----------------------------------------------------
sbs2.com 2 "user" "Susan" <%1 >_._
if errorlevel 1 copy _._ %1
del _._
-----------------------------------------------------
Converts dos textfiles to unix textfiles
-----------------------------------------------------
sbs2.com 0 "$0d" "" <%1 >_._
if errorlevel 1 copy _._ %1
del _._
-----------------------------------------------------
Converts unix textfiles to dos textfiles
-----------------------------------------------------
sbs2.com 0 "$0a" "$0d$0a" <%1 >_._
if errorlevel 1 copy _._ %1
del _._
-----------------------------------------------------
echo without CRLF
-----------------------------------------------------
echo set a=|sbs2.com 0 "$0d$0a" "" >_.bat
-----------------------------------------------------
Remove trailing blanks from all lines
-----------------------------------------------------
:start
sbs2.com 0 " $0d" "$0d" <%1 >_._
if not errorlevel 1 goto ende
copy _._ %1
goto start
:ende
del _._
-----------------------------------------------------
Remove all single CR LF (ascii text file -> WORD)
-----------------------------------------------------
sbs2.com 0 "$0d$0a$0d$0a" "$0a" <%1 >_._
if errorlevel 1 copy _._ %1
sbs2.com 0 "$0d$0a" "" <%1 >_._
if errorlevel 1 copy _._ %1
sbs2.com 0 "$0a" "$0d$0a" <%1 >_._
if errorlevel 1 copy _._ %1
del _._
-----------------------------------------------------
Extract line 5-9 from a text file
-----------------------------------------------------
sbs2.com 4 "$0d$0a" '" <%1 >_._
if errorlevel 1 copy _._ %1
sbs2.com 5 "$0d$0a" "$0d$0a' <%1 >_._
if errorlevel 1 copy _._ %1
-----------------------------------------------------
The source code
-----------------------------------------------------
@=$100
move.w #$81,r5
movu.bw -1.b(r5.w),r2
eor.l r0,r0
eor.l r4,r4
.lab1:
_10: dec.w r2
bmi.w x100
move.b (r5.w),r0
inc.w r5
cmp.b #'0',r0
blo.b _20
cmp.b #'9',r0
bhi.b _20
sub.b #'0',r0
mulsq.l #10,r4,r4
add.l r0,r4
move.w #_30,lab1
br.b _10
_20: jmp.w (lab1)
_30: move.l r4,number
move.w #buf1,r6
bsr.w get_string
or.w r6,r6
beq.b .x100
move.w #buf2,r6
bsr.w get_string
eor.l r5,r5
_a00: move.w #buf1,r6
eor.w r4,r4
_a10: move.b #$3f,m0
move.w #buf0,r1
move.w #1,r2
eor.w r3,r3
trap #$21
bcs.b .x100
or.w r0,r0
beq.b _x100
move.b buf0,r0
cmp.b (r6.w),r0
beq.b _a20
_a50: or.w r4,r4
beq.b _a30
move.w #$4201,r0
move.w #-1,r2
move.w r4,r1
neg.w r1
trap #$21
move.w #buf1,r1
move.w #1,r2
_a30: move.b #$40,m0
inc.w r3
trap #$21
bcs.b .x100
cmp.w #buf2,r1
bne.b _a60
tst.b #1,stop
bne.b _x110
_a60: cmp.w r0,r2
beq.b _a00
.x100: br.b x100
_a20: inc.w r6
inc.w r4
cmp.w buf1l,r4
blo.b _a10
inc.l r5
move.l number,r0
or.l r0,r0
beq.b _a40
cmp.l r0,r5
beq.b _a40
dec.w r4
move.w #buf1,r1
move.w #1,r2
br.b _a50
_a40:
tst.b #1,start
beq.b _a41
move.w #$4200,r0
eor.w r1,r1
eor.w r2,r2
inc.w r3
trap #$21
move.b #$40,m0
trap #$21
dec.w r3
_a41: move.w #buf2,r1
move.w buf2l,r2
br.b _a30
_x100: or.w r4,r4
beq.b _x110
move.w #buf1,r1
move.w r4,r2
br.b _a30
_x110:
move.w r5,r0
or.l r5,r5
beq.b x101
move.l number,r1
or.l r1,r1
beq.b _x120
cmp.l r5,r1
bhi.b x100
move.b #1,r0
br.b x101
_x120: cmp.l #$ff,r5
bls.b x101
move.b #-1,r0
br.b x101
x100: eor.b r0,r0
x101: move.b #$4c,m0
trap #$21
get_string:
eor.w r1,r1
move.w r6,r3
move.w #_10,lab1
move.w #_30,lab2
; move.l #(_30<<16)+_10,lab1 ; kuerzer
_10: dec.w r2
bmi.b _x100
move.b (r5.w),r0
inc.w r5
eor.b m0,m0
cmp.b #'"',r0
beq.b _20
cmp.b #"'",r0
beq.b _21
jmp.w (lab1)
_21: inc.b m0
_20: jmp.w (lab2)
_30: move.w #_40,lab1
move.w #_50,lab2
; move.l #(_50<<16)+_40,lab1 ; kuerzer
move.b m0,start
br.b _10
_40: or.b r1,r1
bne.b _41
cmp.b #'$',r0
bne.b _42
move.w #2,r1
br.b _10
_42: move.b r0,(r6.w)
inc.w r6
br.b _10
_41: or.b #$20,r0
sub.b #'a'-10,r0
bpl.b _43
add.b #'a'-10-'0',r0
_43: lsl.b #4,m1
add.b m1,r0
dec.b r1
beq.b _42
move.b r0,m1
br.b _10
_50: sub.w r3,r6
move.w r6,-2.b(r3.w)
move.b m0,stop
rts.w
_x100: addq.w #2,r7
br.b x100
lab1: dc.w .lab1
lab2: blk.w 1
even
start: blk.b 1
stop: blk.b 1
number: blk.l 1
buf0: blk.w 1
buf1l: blk.w 1
buf1: blk.w 200
buf2l: blk.w 1
buf2: blk.w 200
作者: bat-zw
时间: 2008-7-14 00:27
标题: 也来一个:
感觉思路和效率都还可以,所以发了:
@echo off&setlocal enabledelayedexpansion
for /f "delims=" %%i in (a.txt) do (set str=%%i
if "!str:。=!" neq "!str!" call :lp
if defined str set /p=!str:。=!<nul
)
pause>nul&goto :eof
:lp
set var=%str%
if "%str:~,1%" equ "。" set /p=。<nul&echo.&echo.
set str=%str:。= %
if "%var:~-1%" neq "。" set str=%str%。
for %%i in (%str%) do (set var=%%i
if "!var:~-1!" neq "。" set /p=%%i。<nul&echo.&echo.&set str=!str:%%i=!
)
[
Last edited by zw19750516 on 2008-7-14 at 12:28 AM ]
作者: hackerscans
时间: 2008-7-14 09:20
小菜在这学习了。 也恭喜ZW19750516荣升金牌会员。
作者: HAT
时间: 2008-7-14 09:31
qzwqzw 兄能否写个sed版本的出来?我想学习一下。
我写的不行,管道后面的部分看起来没有起作用。
sed "s/。/。\n/g" a.txt | sed "/。$/!s/\n//g"
作者: lxmxn
时间: 2008-7-14 15:03
标题: 来个 sed 版的。
sed "s/。/&\n\n/g" myfile.txt | sed ":nt; /。$\|^$/!{N;bnt};s/\n//g"
作者: 26933062
时间: 2008-7-14 15:28
Quote: |
Originally posted by lxmxn at 2008-7-14 15:03:
sed "s/。/&\n\n/g" myfile.txt | sed ":nt; /。$\|^$/!{N;bnt};s/\n//g" |
|
头都想破了都没想出来,
版主能解释一下这个地址么?
/。$\|^$/ 这里中间的 这个 管道是或者的意思么?那么前面的 \ 就是转义符号了?
你的代码在句号开头的行时会多显示一空行,我修改如下,不知道会在某种情况下出错吗?
另外:不用管道符号能解决吗?
sed "s/。/&\n\n/g" a.txt | sed ":nt; /。$/!{N;b nt};s/\n//g;n"
[
Last edited by 26933062 on 2008-7-14 at 03:29 PM ]
作者: HAT
时间: 2008-7-14 15:43
斑竹高明,学习了。
不过我发现这样会在原本以句号结尾的行后面添加一个多余的空行,修改如下:
sed "s/。/&\n\n/g" a.txt | sed "/^$/{:a;N;s/^\n$//;ta}" | sed ":a; /。$\|^$/!{N;ba};s/\n//g"
作者: HAT
时间: 2008-7-14 15:47
\是转义符,|不是管道,而是“或”
/。$\|^$/!表示对不是以句号结尾的非空行执行后面的命令
作者: qzwqzw
时间: 2008-7-14 15:53
抱歉,更正一句
实现楼主的意图最简洁、高效和通用的方案
是用change、hexc等全文文本替换工具
而非sed/awk等行缓冲形式的文本编辑工具
因为后者处理跨行问题时语法会过于晦涩
而且兼容性也不是很高
因为sed、awk的多个实现对许多非标准标记支持有很大不同
sed我了解的很少
基本上我就了解了正则表达式的那一部分
其它的没有接触
但我对:nt、{N;b nt}等类似标记的兼容性存疑
[
Last edited by qzwqzw on 2008-7-14 at 03:55 PM ]
作者: lxmxn
时间: 2008-7-14 15:53
嗯,就是或的意思,其实我对sed也不精,自己乱写的一个。。。
作者: HAT
时间: 2008-7-14 16:27
change a.txt /from "&H0D0A" /to null
change a.txt /from "。" /to "。&H0D0A0D0A"
change.exe
http://upload.cn-dos.net/img/427.zip
[
Last edited by HAT on 2008-10-29 at 14:19 ]
作者: 26933062
时间: 2008-7-14 17:21
31 楼思路也是先把a.txt拼接成一行,再替换。
测试同样不行,刚下了个change 试了试,
问一个问题: 在change 中怎么表示不包括某字符的行?
作者: qzwqzw
时间: 2008-7-14 17:34
看样子没什么问题嘛,如何不行?
change不是sed
没有那么多的正则标记
至于不包含指定字符的行
是有一个/v的开关
类似find
[
Last edited by qzwqzw on 2008-7-14 at 05:41 PM ]
作者: qzwqzw
时间: 2008-7-14 17:39
哦,明白了
你没有注意到change是for dos的程序吗?
在win32 console cmd下运行要先初始化中文环境的
chcp 437>nul & graftabl 936>nul
作者: 26933062
时间: 2008-7-14 17:44
Quote: |
Originally posted by qzwqzw at 2008-7-14 17:39:
哦,明白了
你没有注意到change是for dos的程序吗?
在win32 console cmd下运行要先初始化中文环境的
chcp 437>nul & graftabl 936>nul |
|
确实是这个问题,谢谢!
不过我还是想问一下 在change 中怎么表示不包括某字符的行?
我的思路是 先将所有句号都替换成回车、再删除所有不包含句号的行的回车
作者: 26933062
时间: 2008-7-14 17:59
哪里有 change。exe 的教程吗? 帮助信息是英文的我一个都看懂啊!。。。
作者: HAT
时间: 2008-7-14 18:04
我这里有一部分中文帮助,不全。
Quote: |
CHANGE.EXE 是一个以命令行方式处理对文件的修改工具,目标文件可以是任意大小任意格式。可以一次执行30条命令!非常地高效。
一、基本格式:
change 源文件.txt /from “被替换的串” /to “替换串” /in “条件”
二、已知限制是它不支持长名,可能不认识一些windows下的特殊字符作文件名。对此,解决之道是以短文件名访问(例如:myfile~1.txt)。
三、详细功能列表:
⒈處理的文件不限大小,前提是磁盤上至少要有与目标文件等大的预留空间,用于临时存放其副本;
⒉不仅处理文本文件,也处理二进制文件;
⒊替入和换出的字符串长度可以不同;
⒋可以指定替换行为只在特定行发生,特定行的标志是有另一个指定的字符(串)出现,这个字符串还允许大小写敏感;
⒌可以同时执行多达30个修改指令;
⒍支持子目录;
⒎兼容dos/Unix/Mac 文本格式;
⒏输入输出字符串可以是文本的(Ascii),也可以是十六进制值或十进制值;
⒐替换速的特快;
⒑具有备份选项,以防源文件可能损坏;
⒒替换工作可以交互式进行(控制台);
⒓除命令行、控制台它还允许把多条指令组合编制为一个控制文件一次执行;
⒔可以使用布尔变量;
⒕源文件名支持通配符;
⒖"*"用在指定的被修改字符串时,表示由当前位置到行尾的整个子串;
⒗在指定目标字符串时,可以设定“列”,仅当字符位于此范围内时才发生替换;
⒘可以按文件属性排除某个文件不被处理;
⒙可以排除某些行不处理;
⒚按ESC可以中止处理进程。
⒛
四、如何指定参数
当程序运行时,它将以如下三种方式读取参数:
⒈INI文件
⒉系统环境变量
⒊命令行
先看最常用的命令行语法。
To/From/In规范:
FROM 被替换的文字
TO 用于替换的文字
TO (可选)指定发生替换行为的特定行标志
举例,设test.txt文件包含如下两行:
The quick brown fox jumped over
the lazy brown dog.
我们输入:
change /from brown /to red /fox
则文件变为:
The quick red fox jumped over
the lazy brown dog.
即:有出现"fox"的那行"brown:被替换为"red",其它行不变。
如果所指定字符串包含空格或其他特殊字符,请用双引号,比如:
CHANGE test.TXT /FROM "my music" /TO "my video"
或者用十六进制字符处理特殊字符,如:
CHANGE test.TXT /FROM &H0D0A0D0A /TO &H0D0A
(删除多余的行)
设定列宽的例子:
change test.txt /from ok 5/10 /to no
只替换从第5列到第10列的ok 为 no,这个功能是按首字符认定位置的,比如有一个“ok”位于4,5列那么它不会被替换。
仅删除的例子:
change test.txt /from no /to null
(即:删除所有的no)
如果要忽略英文字母的大小写,使用参数 /I
与DOS类似,可以用参数 /s 处理所有子目录中文件的替换工作
替换指定行的例子:
change test.txt /from no /to re /lines 3-8 30-50
(即:只替换3到8行和30到50行的字符)
出于安全目的,该程序总要自动生成一个临时文件备份源文件,如果用 /N文件名 参数另指定一个输出文件,则没有临时文件输出。
要消除文件末尾多余的空格,可以用参数 /trim
使用布尔变量的例子:
CHANGE TEST.TXT /FROM Apple /TO Banana /IN (red OR brown) AND NOT Pear
将替换apple为banana,但所在行必须有red或brown出现,并且没有Pear出现
本程序的返回误码意义:
0 无错,有修改
1 无错,无修改
253 提前中止
254 内部错误
255 语法错 |
|
作者: HAT
时间: 2008-7-14 18:05
//不过我还是想问一下 在change 中怎么表示不包括某字符的行?
/V says to find those items that do NOT match the specification;
作者: 26933062
时间: 2008-7-14 18:14
谢谢我得到的中文帮助信息也是这些,讲的太少了。
change a.txt /from "&H0D0A" /to "yyy&H0D0A" /in 。
我的本意是将包含句号的行的回车替换为yyy加回车,但是怎么没有句号的行末尾也加上了yyy ???
作者: qzwqzw
时间: 2008-7-14 19:10
确实是这个问题,谢谢!
不过我还是想问一下 在change 中怎么表示不包括某字符的行?
我的思路是 先将所有句号都替换成回车、再删除所有不包含句号的行的回车
--------------------
真是较真的厉害
既然已经有了合适的方案
何必要舍易求难?
change有两种工作模式
一种是binary(block)模式
也就是我提到全文文本替换
按块读取字节然后进行替换
对0d0a视同普通字节
另一种是text(record)模式
也就是我说过的行缓冲模式
按行读取文本然后进行替换
对0d0a会作特殊处理
而如果/from /to /in中使用&H十六进制表示的字符
则直接进入binary模式
而/in开关则需要text模式的支持
所以你的替换操作是无效的
下面的命令是个示例
change \test\a.txt /n\test\b.txt /from "文件" /to "file" /in not "File"
作者: 26933062
时间: 2008-7-14 19:17
多谢多谢,又有不少收获。。。。 ^_^
作者: HAT
时间: 2008-7-14 19:34
qzwqzw 的讲解真是详细啊^_^
作者: 26933062
时间: 2008-7-14 23:25
真是郁闷,qzwqzw 兄的示列代码我这么运行不了?
我测试代码如下: xp sp2
:
@echo off
chcp 437>nul & graftabl 936>nul
change \test\a.txt /n \test\c.txt /from "一" /to " yyy " /in not "。"
对这段代码的理解为:
运行test模式、即按行读取。不产生临时文件,新文件在c.txt 中,
替换不含句号的行中的“一”为 “ yyy ”
怎么就是运行不了呢?
作者: qzwqzw
时间: 2008-7-15 00:16
晕!
test是我自己的示例文本文件的相对路径
并非模式
/n后不要跟空格
作者: 26933062
时间: 2008-7-15 13:34
看来它是定要欺负我了,我也这样测试过,还是不行
@echo off
cd.>d\c.txt
chcp 437>nul & graftabl 936>nul
change \d\a.txt /n\d\c.txt /from "一" /to " yyy " /in not "。"
[
Last edited by 26933062 on 2008-7-15 at 01:35 PM ]
作者: lxmxn
时间: 2008-7-15 15:05
按照change的思路,那么sed就可以这样改进一下了
sed ":nt; $!{N; s/\n//; tnt}; s/。/&\n\n/g" myfile.txt
作者: 26933062
时间: 2008-7-15 15:29
Quote: |
Originally posted by lxmxn at 2008-7-15 15:05:
按照change的思路,那么sed就可以这样改进一下了
sed ":nt; $!{N; s/\n//; tnt}; s/。/&\n\n/g" myfile.txt |
|
是可以,但如果文件太大的话就不行了吧,模式空间能容纳太多内容吗?
作者: lxmxn
时间: 2008-7-15 15:44
Quote: |
Originally posted by 26933062 at 2008-7-15 15:29:
是可以,但如果文件太大的话就不行了吧,模式空间能容纳太多内容吗? |
|
嗯,文件大了估计就不成了。
刚才试了一下,10K以下的文件处理起来还是比较快的,但是到了50K以上就比较慢了,过兆的文件就不适合了。
作者: qzwqzw
时间: 2008-7-16 08:20
回45楼
这是我的执行结果
除了改动了测试文件路径
其它没有变
cd.>d\c.txt这句不是必须的
Quote: |
批处理文件(Batch File,简称 BAT文件)是 YYY 种在DOS
下最常用的可执行文件。它具有灵活的操纵性,可适应各
种复杂的计算机操作。所谓的批处理,就是按规定的顺序
自动执行若干个指定的DOS命令或程序。
即是把原来 YYY 个 YYY 个执行的命令汇总起来,成批的执行,而程序文件可
以移植到其它电脑中运行,因此可以大大节省命令反复输
入的繁琐。同时批处理文件还有一些编程的特点
。可以通过扩展参数来灵活的控制程序的执行,所以在日
常工作中非常实用。批处理。bat。cmd。尺有所短。寸有所长。 |
|
作者: 26933062
时间: 2008-7-16 10:25
Quote: |
Originally posted by qzwqzw at 2008-7-16 08:20:
回45楼
这是我的执行结果
除了改动了测试文件路径
其它没有变
cd.>d\c.txt这句不是必须的
|
|
总算试出来了,原来是n后面不能有那个斜杠。。
change f:\111\d\a.txt /nf:\111\d\c.txt /from "nnn" /to " yyy " /in not "。"
qzwqzw 兄,你那里可以有斜杠吗?
作者: qzwqzw
时间: 2008-7-16 13:27
看来你对相对路径和绝对路径缺乏足够的了解
前缀的\指代当前盘的根
很显然
因为你的数据文件不在当前盘
所以导致出错
作者: 26933062
时间: 2008-7-16 14:16
是,对相对路径,一直是模模糊糊的。。。
原来如此。。!
作者: yycmu4
时间: 2008-9-25 21:20
长见识了
作者: metoo
时间: 2008-9-25 21:45
其实awk处理这类问题很方便的。。只是很多人先入为主了
BEGIN {RS="。"}
{
gsub (/\n/,"")
print $0"。"}
老规矩,本人只用代码
作者: wuchan
时间: 2010-1-2 10:45
不知道 change 支持通配符不