Board logo

标题: [文本处理] [已解决]批处理如何删除两个字符之间的多行内容? [打印本页]

作者: zhen    时间: 2011-3-23 15:12     标题: [已解决]批处理如何删除两个字符之间的多行内容?

我在D:\CNC里放有许多.B3文件,需要批处理删除(PART RIPCUT)和(BLOCK)之间的行。但有的文件没有(PART RIPCUT),这些文件不做修改。请各位朋友帮忙!文件内容如下:
(17)
%
P17
(STD WADR)
(ORIGIN=BOTTOM LEFT)
(METRIC)
G71
(RELATIVE)
G91
(PART 1/Top Cheek)
G00X616.8Y820.0
G41
M04

F8000.0
G01X0.0Y-4.0
G03X144.0Y-144.0I144.0J-0.0
G01X50.0Y0.0
G01X4.0Y0.0
M03
G40

(PART 2/Left Throat Wrapper)
G00X-221.2Y205.0
G41
M04
G01X-4.0Y0.0
G01X0.0Y-350.0
G01X0.0Y-4.0
M03
G40
G00X400.0Y4.0
G41
M04
G01X-4.0Y0.0
G01X-99.2Y0.0
G01X-0.8Y3.0
G01X0.0Y-4.0
M03
G40
(PART 1/Bottom Cheek)
G00X429.1Y-813.0
(PART 2/Left Throat Wrapper)
G00X-25.1Y821.0
G41
M04
G01X-4.0Y0.0
G01X-99.2Y0.0
G01X0.0Y-350.0
G01X0.0Y-4.0
M03
G40
G00X361.2Y200.6
G41
M04
G01X0.0Y-4.0
G01X0.0Y-99.2
G01X0.0Y99.2
G01X350.0Y0.0
G01X4.0Y0.0
M03
G40
G00X25.0Y-418.0
G41
M04
G01X0.0Y-4.0
G01X0.0Y-99.2
G01X350.0Y0.0
G01X4.0Y0.0
M03
G40
G00X-4.0Y-392.0
G41
M04
G01X0.0Y-4.0
G01X0.0Y-99.2
G01X350.0Y0.0
G01X4.0Y0.0
M03
G40
(PART 1/Left Throat Wrapper)
G00X345.8Y-385.6
G41
M04

G01X-4.0Y0.0
G01X-49.2Y0.0
G01X0.0Y-4.0
M03
G40

(PART 1/Right Throat Wrapper)
G00X4.0Y365.0
G41
M04

G01X-4.0Y0.0
G01X-49.2Y0.0
G01X0.0Y-350.0
G01X0.0Y-4.0
M03
G40

(PART 2/Left Throat Wrapper)
G00X-13.8Y824.6
G41
M04
G01X0.0Y-4.0
G01X0.0Y-99.2
G01X-3.0Y-0.8
G01X350.0Y0.0
G01X4.0Y0.0
M03
G40
(PART RIPCUT)
G00X23.8Y-1187.6
M04
G01X0.0Y1500.0
M03
(BLOCK)

G00X-1937.6Y-1500.0
(END OF SHEET)
(END OF PROGRAM)
M30

我现有一段代码,但处理文件时,如果部分文件没有(PART RIPCUT),那么(BLOCK)及下面的内容会出现两次重复,怎么解决?
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%a in ('dir /s/b D:\CNC\*.B3') do (
  3. cd.>"%%a_"
  4. for /f "tokens=1,2 delims=:" %%i in ('findstr /n "." "%%a"') do (
  5. set "var=%%j"
  6. if not defined n echo %%j
  7. if defined m echo %%j
  8. if "!var:~1,7!"=="PART RI" set n=%%i
  9. if "!var:~1,5!"=="BLOCK" set m=%%i & echo %%j
  10. ) >> "%%a_"
  11. set n=
  12. set m=
  13. move "%%a_" "%%a"
  14. )
  15. exit
复制代码

作者: 随风    时间: 2011-3-23 15:56

给出这么大段样本文件,你总该把含关键字的行用颜色标明下吧,这样让我们好找。。。
作者: wc726842270    时间: 2011-3-23 18:52

用SED不行么?感觉上非常的恰到好处啊
作者: wc726842270    时间: 2011-3-23 19:12

刚才写了个简单的
  1. @echo off
  2. sed "/(PART RIPCUT)/,/(BLOCK)/d" a.txt
  3. pause
复制代码

作者: Batcher    时间: 2011-3-23 20:51

4# wc726842270


这个简单的过头了吧,要么加个-i,要么加个重定向。
作者: tmplinshi    时间: 2011-3-23 21:31

  1. @echo off
  2. cd /d "D:\CNC"
  3. for /f "delims=" %%f in (' dir /b *.B3 ') do (
  4.     set .Skip=
  5.     set .Move=
  6.     >"%~nx0.tmp" (
  7.         for /f "usebackq delims=" %%s in ("%%f") do (
  8.             if not defined .Skip (
  9.                 echo,%%s
  10.                 if "%%s"=="(PART RIPCUT)" set /a .Skip = 1, .Move = 1
  11.             ) else (
  12.                 if "%%s"=="(BLOCK)" (
  13.                     set .Skip=
  14.                     echo,%%s
  15.                 )
  16.             )
  17.         )
  18.     )
  19.     if defined .Move move "%~nx0.tmp" "%%f"
  20. )
  21. del "%~nx0.tmp" 2>nul
复制代码

作者: zhen    时间: 2011-3-24 08:33

4# wc726842270


sed怎么用啊?这不是XP系统里的命令啊
作者: tmplinshi    时间: 2011-3-24 08:50

本帖最后由 tmplinshi 于 2011-3-24 14:24 编辑

7# zhen

Unix for Windows 批处理命令行工具集
http://bathome.net/thread-1114-1-1.html
作者: zhen    时间: 2011-3-24 09:50

本帖最后由 zhen 于 2011-3-24 09:52 编辑

6# tmplinshi


感谢你的回答,经我测试,完全可以。我想问一下skip和move是什么
if defined 和if not defined怎么解释?
我看你最后用到del命令,不用 if defined .Move move "%~nx0.tmp" "%%f",直接用move "%~nx0.tmp" "%%f"不就行吗?

其实对文件的整个处理过程是这样的:
删除以(打头的行,删除F8000行;
跳过前三行;
替换G41为M23,M04为M10等等;
在M10下面加一行G04 F1000;
如果有(PART RIPCUT),删除(PART RIPCUT)和(BLOCK)之间的行。


请看看我的代码有什么缺陷没有。
@echo off
setlocal enabledelayedexpansion
for /r D:\CNC\ %%i in (*.B3) do (
   cd.>temp.txt
for /f "eol=(" %%j in (%%i) do (
    set str=%%j
    set "str=!str:G41=M23!"
    set "str=!str:M04=M10!"
    set "str=!str:M03=M11!"
    set "str=!str:G40=M22!"
    echo !str!>>temp.txt)
move temp.txt %%i)
echo.
for /r D:\CNC\ %%i in (*.B3) do (
   cd.>temp.txt
   for /f "eol=F skip=3 delims=#" %%j in (%%i) do (
    echo %%j>>temp.txt
     if "%%j"=="M10" echo G04 F1000>>temp.txt)
move /y temp.txt %%i)
echo.
move /y D:\CNC\*.B3 D:\CNC2\ >nul 2>nul
for /r D:\CNC2\ %%i in (*.B3) do (ren "%%i" "%%~ni.CNC")
pause
作者: tmplinshi    时间: 2011-3-24 10:21

本帖最后由 tmplinshi 于 2011-3-24 14:42 编辑

碰到 (PART RIPCUT) 后就定义 .Skip 变量。存在 .Skip 变量的时候,碰到的行会略过。直到碰到 (BLOCK),再把 .Skip 变量清除。

if defined 和 if not defined 就是判断变量有没有定义。

没有出现 (PART RIPCUT) 的时候,文件不会改动,就不执行多余的 move 操作。用 .Move 变量来判断文件有没有改动。
最后的 del 命令也是在没有执行 move 的情况下,把临时文件删除。
现在你说还有其他的修改,.Move 变量就没有必要了。
作者: terse    时间: 2011-3-24 11:28

如此替换 文件其他行含该字符也一起替换的哦
作者: zhen    时间: 2011-3-24 16:04

本帖最后由 zhen 于 2011-3-24 16:47 编辑

10# tmplinshi


你好,你的代码怎么删了?你在代码中提前用了eol=(,后面删除(PART RIPCUT) 和(BLOCK)之间的行就会出问题,我把eol=( 放到后面了,但必须删除临时文件,你给看看吧!还有,为什么.skip=#,=1好像也行,难道任意字符都行吗?这里有什么解释?

@echo off
SetLocal EnableDelayedExpansion
cd /d "D:\CNC"
for /f "delims=" %%i in ('dir /b *.B3') do (
    set .Skip=
    >"%~nx0.tmp" (
        for /f "usebackq skip=7 delims=" %%j in ("%%i") do (
            if not defined .Skip (
                    if "%%j" neq "F8000.0" (
                    set str=%%j
                    set "str=!str:G41=M23!"
                    set "str=!str:M04=M10!"
                    set "str=!str:M03=M11!"
                    set "str=!str:G40=M22!"
                    echo,!str!
                    if "!str!"=="M10" echo G04 F1000
                    if "%%j"=="(PART RIPCUT)" set .Skip=#
                )
            ) else (
                if "%%j"=="(BLOCK)" (
                    set .Skip=
                    echo %%j)
             )
       )
  )
for /f "usebackq eol=( delims=:" %%k in ("%~nx0.tmp") do echo %%k>>"%~nx1.tmp"
move /y "%~nx1.tmp" "%%i")
del "%~nx0.tmp" 2>nul

pause
作者: asnahu    时间: 2011-3-24 16:42

本帖最后由 asnahu 于 2011-3-24 19:59 编辑
  1. sed "1,3d; s/G41/M23/; s/M04/M10\nG04 F1000/; /PART RI/{:a N; /BLOCK/!ba; s/)\n.*(/)\n(/}" test.b3
复制代码

作者: terse    时间: 2011-3-24 18:12

  1. @echo off&setlocal enabledelayedexpansion
  2. set "_M10=G04 F1000"
  3. set "_G41=M23"
  4. set "_M04=M10"
  5. set "_M03=M11"
  6. set "_G40=M22"
  7. set "_F8000= "
  8. set "ph=D:\CNC\"
  9. for /f "skip=3 delims=" %%i in ('dir /s/b "%ph%*.B3"') do (
  10.     set n=
  11.     (for /f "usebackq tokens=*" %%j in ("%%i") do (
  12.             if /i "%%~nj"=="(BLOCK)" set "n="
  13.             if not defined n (
  14.                if "!_%%~nj!" == "" (set "str=%%j") else set "str=!_%%~nj!"
  15.             )
  16.             if /i "%%~nj"=="(PART RIPCUT)" set n=i
  17.             if "!str!" neq " " if "!str:~,1!" neq "(" echo !str!
  18.     ))>"%%i_tem~"
  19.     rem move "%%i_tem~" "%%i"
  20. )
  21. pause
复制代码

作者: zhen    时间: 2011-3-25 11:30

14# terse


你的代码怎么一点效果也没有?
作者: terse    时间: 2011-3-25 11:48

15# zhen
去掉 rem move "%%i_tem~" "%%i"  这里的rem  
注意备份原文件




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2