【问题标题】:preserve empty lines in a text file while using batch for /f在对 /f 使用批处理时保留文本文件中的空行
【发布时间】:2016-08-02 14:43:36
【问题描述】:

我一直在尝试使用批处理脚本在文本文件中查找和替换字符串。我遇到了this answer,它几乎解决了我的问题,但空行没有保留在输出文件中。我试过this answer too,但行以行号开头[] ... [17]

任何帮助扩展this answer 以在输出文件中保留空行将不胜感激。 谢谢

    setlocal enableextensions disabledelayedexpansion

set "search=<Tool>"
set "replace=XYZ"

set "textFile=C:\abc.txt"

for /f "delims=" %%i in ('type "%textFile%" ^| find /v /n "" ^& break ^> "%textFile%"') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    set "line=!line:%search%=%replace%!"
    >>"%textFile%" echo(!line!
    endlocal
)

输出如下所示:

【问题讨论】:

  • 您需要显示您在问题中尝试过的代码。
  • @Squashman 谢谢你的评论,我已经添加了我尝试过的代码。

标签: batch-file


【解决方案1】:

您没有认真研究第二个链接的答案 - 它有一个非常有效的解决方案。

我更喜欢这种技术的变体,它使用*]= 替换而不是子字符串:

@echo off
setlocal enableextensions disabledelayedexpansion

set "search=<Tool>"
set "replace=XYZ"

set "textFile=C:\abc.txt"

for /f "delims=" %%i in ('type "%textFile%" ^| find /v /n "" ^& break ^> "%textFile%"') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    set "line=!line:*]=!"
    if defined line set "line=!line:%search%=%replace%!"
    >>"%textFile%" echo(!line!
    endlocal
)

但是代码没有优化——附加重定向会减慢速度,因为必须打开输出文件,并且每次循环迭代都必须将文件指针定位到文件末尾。在循环之外重定向到一个临时文件,然后使用 MOVE 将原始文件替换为临时文件,速度要快得多。

我也更喜欢使用 FINDSTR 而不是 FIND - 它可以更好地处理长行,并且不需要管道或重定向。

@echo off
setlocal enableextensions disabledelayedexpansion

set "search=<Tool>"
set "replace=XYZ"

set "textFile=C:\abc.txt"

>"%textFile%.new" (
  for /f "delims=" %%i in ('findstr /n "^" "%textFile%"') do (
      set "line=%%i"
      setlocal enabledelayedexpansion
      set "line=!line:*:=!"
      if defined line set "line=!line:%search%=%replace%!"
      echo(!line!
      endlocal
  )
)
move /y "%textFile%.new" "%textFile%" >nul

说实话,我再也不使用纯批处理来修改文本文件了。有太多的边缘情况需要大量神秘的代码来解决。上面的代码还有很多潜在的问题。例如:

  • 搜索字符串不能包含=
  • 搜索字符串不能以*! 开头
  • 替换字符串不能包含!
  • 如果搜索和/或替换同时包含" 以及&amp;| 等有毒字符,则替换可能会失败。

我改用JREPL.BAT regular expression find/replace utility。它更快、更健壮、更强大。它是纯脚本(混合批处理/JScript),可以在从 XP 开始的任何 Windows 机器上本地运行,无需任何第三方 exe 文件。

例如,以下简单命令可以非常快速地查找/替换您的文字。

call jrepl "<Tool>" "XYZ" /l /f "C:\abc.txt" /o -

【讨论】:

  • 感谢您的回答和解释。它起作用了:)我也尝试了FINDSTR而不是FIND,我得到了一些奇怪的输出。但是,您的解决方案按预期工作..:)
  • 嗨@dbenham,你能告诉我echo(!line!做什么吗?我的意思是'('在这有什么用?
  • @atul_pant - 在许多极端情况下,echo !line! 和其他更常见的形式可能会失败 - 这意味着打印的内容不是变量的内容。通过许多人的实验,已经确定echo( 是唯一保证工作的形式,无论接下来发生什么。我知道它很丑,但它确实有效。
  • 谢谢。是否有任何文档说明在 echo 之后究竟做什么?就像我们在启用延迟扩展时在变量名周围使用 ! 一样,与 echo 一起使用时,'(' 是否有类似的含义,就像上面所做的那样?
猜你喜欢
  • 2020-09-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-08
  • 1970-01-01
  • 1970-01-01
  • 2022-10-18
  • 2021-05-21
  • 1970-01-01
相关资源
最近更新 更多