忽略批处理文件中的百分号

Sta*_*agg 30 escaping batch-file

我有一个批处理文件,将文件从一个文件夹移动到另一个文件夹 批处理文件由另一个进程生成.

我需要移动的一些文件中包含字符串"%20":

move /y "\\myserver\myfolder\file%20name.txt" "\\myserver\otherfolder"
Run Code Online (Sandbox Code Playgroud)

这会失败,因为它试图找到一个名称为的文件:

\\myserver\myfolder\file0name.txt
Run Code Online (Sandbox Code Playgroud)

有什么办法可以忽略%吗?我无法改变生成的文件以逃避这种情况,例如加倍百分号(%%),逃避/^(插入符号)等.

rud*_*d3y 51

%%在这种情况下你需要使用.通常使用^(插入符号)会起作用,但是对于%需要加倍的符号.

%%1or %%i或的情况下echo.%%~dp1,因为%指示来自命令或变量的输入(当用%; 包围时%variable%)

为了达到你的需求:

move /y "\\myserver\myfolder\file%%20name.txt" "\\myserver\otherfolder"
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助!


mkl*_*nt0 19

问题的标题非常通用,这不可避免地吸引了许多寻求通用解决方案的读者.
相比之下,OP的问题是奇特的:需要处理自动生成的批处理文件,该文件格式错误且无法修改:%标记未正确转义.
接受的答案提供了一个巧妙的解决特定的 -和异国情调的-问题,但势必会关于制造混乱通用的问题.

如果我们关注通用问题:

如何在批处理文件/命令行中%用作文字字符?

  • 批处理文件%%%,无论是否在不带引号的字符串中,总是以转义 ; 以下产量My %USERNAME% is jdoe,例如:

    echo My %%USERNAME%% is %USERNAME%
    echo "My %%USERNAME%% is %USERNAME%"
    
    Run Code Online (Sandbox Code Playgroud)
  • 命令行上(交互式) - 以及使用脚本语言shell调用函数 - 行为从根本上不同于批处理文件内部:从技术上讲,% 不能在那里进行转义,并且没有单一的解决方法适用于所有情况:

    • 在不带引号的字符串中,您可以使用" ^名称 - 破坏者"技巧:为简单起见,在每个字符之前放置一个字符^%,但请注意,即使您在技术上没有以这种方式转义 %(请参阅下面的详细信息); 例如,以下再次产生如下My %USERNAME% is jdoe:

      echo My ^%USERNAME^% is %USERNAME%
      
      Run Code Online (Sandbox Code Playgroud)
    • 双引号字符串,你无法逃避%的一切,但也有变通方法:

      • 您可以使用上面提到的不带引号的字符串,然后需要您额外地 ^覆盖所有其他shell元字符,这很麻烦; 这些元字符是:<space> & | < > "

      • 或者,如果目标程序支持它(应该使用大多数二进制可执行文件,而不是批处理文件),则可以表示%字符.作为"%" ; 例如:

        echo "My "%"USERNAME"%" is %USERNAME%"
        
        Run Code Online (Sandbox Code Playgroud)
    • 脚本语言,如果你知道你正在调用二进制可执行文件,你可以通过放弃shell -invoking函数来支持"无shell"变体,例如使用而不是在Node中避免整个问题. JS.execFileSyncexecSync


可选的背景信息re 命令行(交互式)使用:

对本节提供帮助的jeb帽子的提示.

命令行上(交互式地),%技术上根本不能被转义 ; 虽然^一般 cmd.exe的转义字符,它并没有应用到%.

如前所述,有没有为解决双引号的字符串,但也有变通方法不带引号的字符串:

" ^名称破坏者"技巧(类似的东西^%USERNAME^%)的作用是:

  • 它"扰乱" 变量名称 ; 也就是说,在上面的示例中cmd.exe查找名为的变量USERNAME^,(希望)不存在.

  • 在命令行上 - 与批处理文件不同 - 对未定义变量的引用保持原样.

从技术上讲,单一 ^变量名内-内的任何地方,只要它不是旁边另一个^-就足够了,让%USERNAME^%举例来说,就足够了,但我建议采取的有条不紊放置约定^ 每前 % 为简单起见,因为它也可以用于诸如up 20^%甚至不需要中断但是是良性的情况,所以你可以有条不紊地应用它,而不必考虑输入字符串的细节.

^的前开放 %,而不是必需的,是良性的,因为^逃逸第二天字符时,它是否需要逃避-或者,在这种情况下,可以进行转义-与否.实际效果是这些^实例最终会从不带引号的字符串中删除.

很大程度上假设的警告:^实际上是变量名称中合法字符(参见评论中的jeb示例); 如果你的变量名结尾 ^,只需将"颠覆性" ^的某处其他变量名,只要它不直接旁边另一个^(因为这将导致^出现在结果字符串中).
也就是说,在(非常不可能)事件中,你的变量有一个名字,比如^b^,你运气不好.


小智 14

在批处理文件中,百分号可以通过使用双百分号(%%)来"转义".这样,将在命令行中使用单个百分号.来自http://www.robvanderwoude.com/escapechars.php

  • 要理解为什么百分号只能通过百分号而不是插入符号进行转义,您可以阅读[如何cmd.exe解析脚本](http://stackoverflow.com/questions/4094699/how-does -the - 窗口的命令解释器-CMD-EXE-解析的脚本/ 4095133#4095133) (5认同)

Mar*_*off -3

您应该能够使用插入符号 (^)来转义百分号

编者注:该链接现已失效;无论哪种方式:它%本身都会转义%,但仅在批处理文件中转义,而不是在命令提示符下转义;^ never escapes %,但在命令提示符下可以间接使用它来防止变量扩展,仅在不带引号的字符串中。

消失的原因%2是批处理文件正在替换传入的第二个参数,而您似乎没有第二个参数。解决这个问题的一种方法是实际尝试,foo.bat ^%1 ^%2...以便当%2在命令中遇到 a 时,它实际上被替换为文字%2

  • 不能用插入符号转义百分号,只能用百分号 (25认同)
  • @mklement0 从技术上讲,您无法在命令行上转义百分号。它似乎有效的唯一原因是 cmd.exe 在 `%username^%` 中搜索变量 `username^`,因此您也可以使用 `%user^name%` 它与转义百分比无关。顺便说一句,“foo.bat ^%1 ^%2”根本没有用,因为在扩展“%1”和“%2”后,插入符号被简单地删除了。另请参阅[如何扩展变量](http://stackoverflow.com/a/7970912/463115) (3认同)