Board logo

标题: [文本处理] [已解决]批处理For命令能否实现只处理某一文本中的某一特定行? [打印本页]

作者: Lumiere    时间: 2009-3-24 15:20     标题: [已解决]批处理For命令能否实现只处理某一文本中的某一特定行?

如题,解释明确点就是,如果我现在有个文本1.txt,里面内容格式不定,字符也很杂乱,但是没有空行,能否用FOR的某一命令格式实现只单独从里面取一个特定的行进行操作?如果不行,什么其他命令可以达到这样的目的?

[ 本帖最后由 Lumiere 于 2009-7-17 15:24 编辑 ]
作者: 随风    时间: 2009-3-24 15:41

特定的行是指什么?
是指定第几行?还是指定某内容的行?还是指定含有某内容的行?
作者: Lumiere    时间: 2009-3-24 15:50     标题: 回复楼上

多谢回复。指定含有某内容的行应该用findstr比较好实现的吧?我想指定行数,不是看内容。比如我想要第二10行,代码形式如何?
作者: 随风    时间: 2009-3-24 15:59

提取文本指定的行
以下代码都未考虑文本中有空行的情况。其中n为指定的行。
代码一、
  不产生临时文件,利用for的skip跳过指定行的前面的行,
  当指定行为第一行时则自动省略skip参数。
  1. @echo off
  2. set /a n=10
  3. set /a n-=1
  4. call :loop %n%
  5. pause
  6. :loop
  7. if %n% lss 1 (set skip=) else (set skip=skip=%n%)
  8. for /f "%skip% delims=" %%a in (a.txt) do echo %%a&goto :EOF
  9. goto :EOF
复制代码
代码二、
  利用more跳过指定行的前面行,当指定行为第一行时则自动用type来取代more
  1. @echo off
  2. set /a n=10
  3. set /a n-=1
  4. call :loop %n%
  5. pause
  6. :loop
  7. if %n% lss 1 (set skip=type) else (set skip=more +%n%)
  8. for /f "delims=" %%a in ('%skip% a.txt') do echo %%a&goto :EOF
  9. goto :EOF
复制代码
代码三、
  利用findstr首先将每行加上行号,在用findstr提取以指定行加冒号开头的行。
  1. @echo off
  2. set /a n=10
  3. for /f "tokens=1* delims=:" %%a in ('findstr /n .* a.txt^|findstr /b %n%:')do echo %%b
  4. pause
复制代码
代码四、
  用goto跳出for
:
  1. @echo off&setlocal enabledelayedexpansion
  2. set /a n=10
  3. for /f "delims=" %%a in (a.txt) do (
  4.    set /a max+=1
  5.    if !max! equ %n% set var=%%a&goto loop
  6. )
  7. :loop
  8. echo %var%
  9. pause
复制代码
代码五、
  产生临时文件,适合大文本,原理同上。
  1. @echo off
  2. set /a n=10
  3. findstr /n .* a.txt|findstr /b %n%:>tem
  4. set /p var=<tem
  5. echo %var:*:=%
  6. pause
复制代码

作者: Batcher    时间: 2009-3-24 17:33     标题: 回复 3楼 的帖子

请把所有的需求都更新到顶楼,以便他人查看。
作者: Lumiere    时间: 2009-3-26 09:50

for命令不是循环命令么?拿你给的第一个代码来看,call :loop %n%, 里面的for /f "%skip% delims=" %%a in (a.txt) do echo %%a&goto :EOF这句可以达到略过前n行,但是第n行和其后的所有行不都要被处理么?是不是在for后面连接一个&goto:eof就可以让它循环一次就跳出来回到call后面继续执行?&命令是连接命令,前一个执行完才执行后面的,不管成败。前面的for没循环完可以执行后面的goto么?有些不理解。

[ 本帖最后由 Lumiere 于 2009-3-26 09:51 编辑 ]
作者: Lumiere    时间: 2009-7-17 09:55     标题: 回复 4楼 的帖子

随风兄,太佩服你了。之前工作的事忙,一直没有时间认真看这代码。多谢你这么敬业给出5个这么优秀的不同代码。不过小弟不才,现在仍然有几个问题有待解疑。
1.为什么第五个代码只适合大文本?
2.第五个代码最后一个命令echo %var:*:=%里边的*是什么意思,按你的思路看应该是要把之前加入的序号还有冒号一起去掉,那*应该是%n%才对吧?
3,最后想问下,能否用批处理实现在原文件上改动,儿而不生成其他的文本。上面的命令都是在命令行窗口显示出来。如果我有一个文本1.txt,里面内容如下,为简便起见我用省略号代替了多半无关痛痒的内容:
..............................
........................
我讨厌批处理之家                 /这就是要处理的行,假设是文本中的第十行
.........................
........................

如果我想用批处理实现将上文中第十行“我讨厌批处理之家”修改为“我喜欢批处理之家”,就在1.txt里改,而不是通过命令修改以后重定向到2.txt,能实现么?

4.随风兄你第一和第二段代码中最后一句goto: EOF应该省略也可以吧,是不是为了代码严谨性考虑?加了就严谨了么,能否进一步解释一下?

欢迎其他仁兄过来指点迷津,不胜感激!

[ 本帖最后由 Lumiere 于 2009-7-17 10:00 编辑 ]
作者: Batcher    时间: 2009-7-17 11:01     标题: 回复 7楼 的帖子

1、代码五既适合大文本又适合小文本,而且对于大文本效率较高;

2、set命令的帮助文档里面有解释:
Environment variable substitution has been enhanced as follows:

    %PATH:str1=str2%

would expand the PATH environment variable, substituting each occurrence
of "str1" in the expanded result with "str2".  "str2" can be the empty
string to effectively delete all occurrences of "str1" from the expanded
output.  "str1" can begin with an asterisk, in which case it will match
everything from the beginning of the expanded output to the first
occurrence of the remaining portion of str1.


3、可以使用sed/change等第三方命令行工具(其实它们也是通过临时文件来实现的,只是没让你看到过程而已);

4、你不是已经测试过了么?
作者: Lumiere    时间: 2009-7-17 15:23     标题: 回复 8楼 的帖子

多谢管理员batcher,问题已明朗,赞一个!




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