【问题标题】:How to output exclamation mark with EnabledDelayedExapnsion?如何使用 EnabledDelayedExapnsion 输出感叹号?
【发布时间】:2014-05-06 15:31:35
【问题描述】:

我正在编辑一个 XML 文件,前 10 行大约是 cmets。而对于 xml cmets 的形式是

<!--  COMMENT HERE   -->

但是当使用我的代码时它不会输出那个!标记,它搞砸了 xml 中的 cmets。我知道 ENABLEDELAYEDEXPANSION 这样做是因为它认为感叹号正在扩展变量。我怎样才能让它工作?

下面是我的代码

setlocal ENABLEDELAYEDEXPANSION

set line=0

FOR /f "usebackqdelims=" %%a in ("%filename2%") do (
    set /a line = !line!+1 
    if !line!==39 (echo REPLACED TEXT39>>%tempfile%
)else if(!line!==45 (echo REPLACED TEXT45>>%tempfile%
)else (echo %%a>>%tempfile%
))

EDIT1 基本上它应该做的是按原样输出每一行,除非它是第 39 行或第 45 行。它可以工作,除了 ! cmets 中的标记不会被输出,它们不再是 cmets。

EDIT2

set line=0

FOR /f "usebackqdelims=" %%a in ("%filename2%") do (
setlocal ENABLEDELAYEDEXPANSION
    set /a !line! +=1
echo !line!
    if !line!==39 (
echo REPLACED TEXT39>>%tempfile%
endlocal
)else if !line!==45 (
echo REPLACED TEXT45>>%tempfile%
endlocal
)else (
endlocal
setlocal DISABLEDELAYEDEXPANSION
echo %%a>>%tempfile%
endlocal
))

这是我一直在使用的最新代码。它效果最好,但现在的问题是变量“line”没有得到更新。我有一种感觉,这是因为“endlocal”。唯一的问题是我需要那里的“endlocal”,否则我会收到错误

已达到最大 setlocal 递归级别。

问题是,我需要在 enableddelayedexpansion 和 disabledelayedexpansion 之间切换,这样我的感叹号才能正确显示。但要做到这一点,我需要跟上“endlocal”调用,我认为这会弄乱我的 line 变量。有什么想法吗?

【问题讨论】:

  • else if 不是命令,您需要空格 ala ) else (
  • 哦,好的,我可以稍后解决这部分问题...
  • if(!line!==45是非法的,应该是if !line!==45
  • set /a !line! +=1 不能工作,因为!line! 将被扩展为空。并且不需要在 enabledDelExp 中使用set /a line+=1

标签: shell batch-file


【解决方案1】:

这种方式不能输出感叹号。

感叹号是%%a的内容的一部分,但是在启用延迟扩展时你不能访问它,因为它会在%%a被扩展后被解析。

因此您需要完全或暂时禁用延迟扩展。

暂时禁用它的示例

setlocal ENABLEDELAYEDEXPANSION

set line=0

FOR /f "usebackqdelims=" %%a in ("%filename2%") do (
    set /a line = !line!+1 
    if !line!==39 (
      echo REPLACED TEXT39>>%tempfile%
    ) else if !line!==45 (
      echo REPLACED TEXT45>>%tempfile%
    ) else (
      setlocal DisableDelayedExpansion
      echo %%a>>%tempfile%
      endlocal
    )
)

或者你根本不使用它,那么你只需要让if line=42部分工作。
这使用了以 0 为模的事实,将产生错误(被 2&gt;nul 抑制)并且变量保持不变,在这种情况下它们保持未定义。

setlocal DisableDelayedExpansion
set line=0

FOR /f "usebackqdelims=" %%a in ("%filename2%") do (
    set /a line+=1
    set "notLine39="
    set /a "notLine39=1%%(line-39)" 2>nul
    set "notLine45="
    set /a "notLine45=1%%(line-45)" 2>nul

    if not defined line39 (
      echo REPLACED TEXT39>>%tempfile%
    ) else if not defined line45 (
      echo REPLACED TEXT45>>%tempfile%
    ) else (
      setlocal DisableDelayedExpansion
      echo %%a>>%tempfile%
      endlocal
    )
)

编辑:为您更改的问题添加了解释
这使用了 SO: Batch files: How to read a file?
中描述的切换延迟扩展技术 诀窍是在将%%a 转移到text 时处于 disabledDelayedExpansion 状态,然后切换到 enabledDE 并能够使用扩展语法。
但是在下一个循环开始之前不要忘记endlocal

setlocal DisableDelayedExpansion
set line=0

FOR /f "usebackqdelims=" %%a in ("%filename2%") do (
    set /a line+=1
    set "text=%%a"
    setlocal EnableDelayedExpansion
    if !line!==39 (
      echo REPLACED TEXT39>>%tempfile%
    ) else if !line!==45 (
      echo REPLACED TEXT45>>%tempfile%
    ) else (
      echo %%a>>%tempfile%
    )
    endlocal
)

【讨论】:

  • 好的,这个新的问题是line39总是未定义的,它总是会打印出“REPLACED TEXT39”,我不确定如何“set /a”notLine39=1%%% %(line-39)" 2>nul" 这行工作正常,但是如果它到达该行,是否将其设置为 null ?如果是,也许我们最初在 notLine39 中设置了一些东西?这样“如果未定义第 39 行”只有在第 39 行时才会为真?
  • 同样经过简短的简单测试回显该行,它似乎没有增加......
  • @JeremyRowler - notLineNN 的定义中有一个错误:百分比太多。通过在两个地方删除两个百分比来解决所有问题。答案已更新。
  • 谢谢@dbenham,我以前玩过'call set /a "notLine39=1%%%%(line-39)"'和errorlevel。然后我忘了删除它:-)
猜你喜欢
  • 2023-03-19
  • 2014-02-04
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-01
  • 2022-01-03
相关资源
最近更新 更多