Board logo

标题: 出题:整理文本 (新手老鸟都来试试) [打印本页]

作者: 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 支持通配符不