Board logo

标题: [文本处理] 批量删除多个txt文件中指定的多行内容的批处理求指点迷津 [打印本页]

作者: lzyecho    时间: 2014-1-7 00:02     标题: 批量删除多个txt文件中指定的多行内容的批处理求指点迷津

下面代码是意思是批量删除多个txt文件中指定的多行内容,本人在学习,有些地方不懂,请版主与各位指教!先谢。
1. 为什么要在for循环中的do语句中设置一个变量x ? x=!x! 的含义是什么(我知道 “!!”是变量延迟中引用的变量的意思)?不明白变量为什么是同一个字母x,要给自己?
2.请较详细解释一下下面整个for循环语句的含义。(本人理解sed语句的意思是删除txt中指定的行,即变量x所指代的行)
3.作者在下面代码中 3>nul  含义是什么? 一般要表示不显示正确或与错误的执行结果要用 1>nul 2>nul  吗?
  1. @echo off 2>nul 3>nul
  2. SetLocal EnableDelayedExpansion
  3. set/p v=请输入要删除的行号并回车,若指定多行请用空格隔开(如:2 5 8):
  4. for %%i in (%v%) do set x=!x! %%i
  5. sed -i '%x%d' *.txt
  6. pause
复制代码

作者: DAIC    时间: 2014-1-7 08:49

  1. @echo off
  2. SetLocal EnableDelayedExpansion
  3. set/p v=请输入要删除的行号并回车,若指定多行请用空格隔开(如:2 5 8):
  4. for %%i in (%v%) do (
  5.     set x=!x! %%id;
  6.     echo !x!
  7. )
  8. echo sed -i "%x%" *.txt
  9. pause
复制代码
这样能看懂吗?
作者: tianyaoxing    时间: 2014-1-7 10:12

回复 2# DAIC


    set x=!x! %%id 里面加个d让新人更难接受, 直接 x=!x! %%i 这句其实和x=%%i效果一样
作者: DAIC    时间: 2014-1-7 10:21

回复 3# tianyaoxing
  1. @echo off
  2. SetLocal EnableDelayedExpansion
  3. set/p v=请输入要删除的行号并回车,若指定多行请用空格隔开(如:2 5 8):
  4. for %%i in (%v%) do (
  5.     set x=!x! %%i
  6.     echo !x!
  7. )
  8. pause
复制代码
  1. @echo off
  2. SetLocal EnableDelayedExpansion
  3. set/p v=请输入要删除的行号并回车,若指定多行请用空格隔开(如:2 5 8):
  4. for %%i in (%v%) do (
  5.     set x=%%i
  6.     echo !x!
  7. )
  8. pause
复制代码
你分别执行这两个代码,看看一样吗?
作者: lzyecho    时间: 2014-1-7 13:15

回复 4# DAIC


    大家好,我分别执行了你们所修改的代码,虽能执行,但显示结果各不相同.   最主要的是,都不能满足原程序最基本的要求:删除指定的行!!
请帮我解释我提出的问题,我是看不懂那些意思,谢谢。
作者: DAIC    时间: 2014-1-7 14:46

回复 5# lzyecho


4楼的代码是为了告诉你,你所认为的直接 x=!x! %%i 这句其实和x=%%i效果一样这个观点是错误的。
如果要删除多行,请把2楼第八行的echo删掉。再试试。
作者: lzyecho    时间: 2014-1-7 16:51

回复 6# DAIC
   首先感谢您的回答!但 “直接 x=!x! %%i 这句其实和x=%%i效果一样 ” ,这个是3楼的观点,我还在学习中。我在一开始提出的问题换没解决:
1. 为什么要在for循环中的do语句中设置一个变量x ? x=!x! 的含义是什么?不明白变量为什么是同一个字母x,要给自己?
2.请较详细解释一下下面整个for循环语句的含义。(本人理解sed语句的意思是删除txt中指定的行,即变量x所指代的行)
3.作者在下面代码中 3>nul  含义是什么? 一般要表示不显示正确或与错误的执行结果要用 1>nul 2>nul  吗?
请给以说明,谢谢。
作者: DAIC    时间: 2014-1-7 17:58

回复 7# lzyecho


set x=!x! %%i
蓝色部分是一个整体,你不能把它分开看。
作者: apang    时间: 2014-1-7 21:25

@echo off 2>nul 3>nul
句柄2(StdErr)默认指向con,首先备份句柄2的指向到句柄3,把句柄2重定向到空设备(nul);再备份句柄3(此时指向con)到句柄4,把句柄3重定向到nul
结果就是:2指向nul,3指向nul,4指向con
执行完毕,恢复原指向(取回备份):句柄2取回句柄3中的nul,3取回4中的con,4还原为undefined
因为现在句柄2始终指向nul,也就可以屏蔽所有语句的错误输出。

如果没有3>nul,即@echo off 2>nul,语句执行完毕,句柄2就会还原为con,屏蔽错误输出仅对当前语句有效,对后面的语句无效。
作者: DAIC    时间: 2014-1-8 08:52

鉴于你顶楼的代码是错误的,我按照2楼的代码倒着讲一次:
代码的最终目的是要调用sed命令删除多行
所以前面的一段BAT代码是为了构造成类似这种格式:
sed -i "2d; 5d; 8d;" *.txt
怎样把用户输入的字符 2 5 8 改变成需要的格式呢?
这就是 for 循环的作用了
它依次遍历 2 5 8 这三个数字
每处理一个数字,就在后面加上字母d和分号,赋值给变量x
最终得到 2d; 5d; 8d;
把它放在sed命令里面去执行就行了:
  1. @echo off
  2. SetLocal EnableDelayedExpansion
  3. set/p v=请输入要删除的行号并回车,若指定多行请用空格隔开(如:2 5 8):
  4. for %%i in (%v%) do (
  5.     set x=!x! %%id;
  6.     REM 下面这行是为了让你看清楚执行过程
  7.     echo !x!
  8. )
  9. sed -i "%x%" *.txt
  10. pause
复制代码

作者: lzyecho    时间: 2014-1-9 13:10

终于看懂了,感谢DAIC  、apang  两位的详细讲解,向各位学习了!!




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