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

时间:2009-12-15 12:20:03

标签: batch-file escaping

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

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

move /y "\\myserver\myfolder\file%20name.txt" "\\myserver\otherfolder"

尝试查找名称为

的文件时失败
\\myserver\myfolder\file0name.txt

有没有办法忽略%?我无法更改生成的文件以逃避此操作,例如将百分号(%%)加倍,使用/^(插入符号)转义等等。

6 个答案:

答案 0 :(得分:46)

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

对于%%1%%iecho.%%~dp1,因为%表示来自命令或变量的输入(当用%包围时; %variable%

实现您的需求:

move /y "\\myserver\myfolder\file%%20name.txt" "\\myserver\otherfolder"

我希望这有帮助!

答案 1 :(得分:18)

问题的标题非常泛型,这不可避免地吸引了许多寻找通用解决方案的读者。
相比之下,OP的问题是异国情调 :需要处理自动生成的批处理文件,该文件格式错误且无法修改< / em>:%标志未正确转义。
accepted answer特定的 - 和异国情调 - 问题提供了一个聪明的解决方案,但必然会对泛型问题产生混淆。

如果我们专注于通用问题

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

  • 批处理文件中,始终以% 的形式转义%%,无论是否在未加引号的字符串中;以下产生My %USERNAME% is jdoe,例如:

    echo My %%USERNAME%% is %USERNAME%
    echo "My %%USERNAME%% is %USERNAME%"
    
  • 命令行 (以交互方式) - 以及使用 shell调用函数时的< em>脚本语言 - 行为基本与内部批处理文件不同 :技术上, % 无法在那里转义 并且没有单一解决方法适用于所有情况

    • 未加引号字符串中,您可以使用&#34; ^名称中断&#34;诀窍:为简单起见,在每个^字符之前放置%,但请注意,即使您在技术上逃避 %那样(见下文了解更多);例如,以下再次产生类似My %USERNAME% is jdoe

      的内容
      echo My ^%USERNAME^% is %USERNAME%
      
    • 双引号字符串中,根本无法逃脱% ,但解决方法

      • 您可以使用上面的不带引号的字符串,然后要求您另外 ^ - 转义所有其他shell元字符,这很麻烦;这些元字符是:<space> & | < > "

      • 或者, 如果目标程序支持应该使用大多数二进制可执行文件 ,但不能使用批处理文件),您可以代表%个字符。作为"%" ; e.g:

        echo "My "%"USERNAME"%" is %USERNAME%"
        
    • 来自脚本语言 ,如果您知道调用二进制可执行文件 ,你可以通过放弃 shell -invoking函数来避免整个问题,转而支持&#34; shell-free&#34;变体,例如using execFileSync instead of execSync in Node.js.

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

jeb求助于本节的提示。

命令行(以交互方式),%技术上可以完全不转义 ;虽然^ 通常是 cmd.exe的转义字符,但它 不适用于%

如前所述,双引号字符串有 no 解决方案,但 的引用 / em> strings:

&#34; ^名称破坏者&#34;技巧(如^%USERNAME^%)工作是:

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

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

从技术上讲,变量名称中的 ^ - 在其中的任何位置,只要它不在另一个^旁边 - 就足够了,所以例如,%USERNAME^%就足够了,但我建议采用在每个 ^ 之前有条不紊地放置% 的惯例为简单起见 ,因为它也适用于up 20^%这样的情况,其中中断甚至不是必需的,但是是良性的,所以你可以有条不紊地应用它 / em>,无需考虑输入字符串的细节。

打开 ^之前的%虽然不是必需的,但却是良性的,因为^会转义下一个字符,无论该字符是否需要转义 - 或者,在这种情况下,可以转义 - 或不转义。最终结果是,此类^实例最终将从未加引号字符串中删除

很大程度上假设的警告^实际上是变量名称中的合法字符(请参阅注释中的jeb&#39;示例);如果你的变量名 ^结尾,只需放置&#34;破坏性的&#34; ^变量名称中的某个 else ,只要它不直接与另一个^相邻(因为这会导致^出现在结果字符串中。) 也就是说,在(非常不可能)事件中,您的变量的名称如^b^,您运气不好。

答案 2 :(得分:14)

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

答案 3 :(得分:1)

我想我已经有了部分解决方案。如果您只想传输名称中包含“%20”字符串且不寻找更广泛解决方案的文件,则可以使用%% 2作为第二个参数调用第二个批处理文件。这样,当你的程序在文本名称中遇到%2时尝试获取第二个参数时,它会用转义的%2替换%2,保持文件名不变。

希望这有效!

答案 4 :(得分:1)

如何“退出”批处理文件并修改文件** 最初的问题是关于一个生成的文件,该文件不能被修改,但包含以下行:

move /y "\\myserver\myfolder\file%20name.txt" "\\myserver\otherfolder"

可以通过使用适当的参数(%1%2,...)调用脚本来部分解决

@echo off

set "per=%%"
call generated_file.bat %%per%%1 %%per%%2 %%per%%3 %%per%%4

这只是将参数设置为:

arg1="%1"
arg2="%2"
...

如何在命令行上添加文字百分号

mklement0 describes the problem,在命令行中转义百分号非常棘手,并且用引号引起来似乎是不可能的。

但一如既往,可以通过一点技巧解决。

for %Q in ("%") do echo "file%~Q20name.txt"

%Q包含"%"%~Q仅扩展到%,与引号无关。

或者避免使用%~

for /F %Q in ("%") do echo "file%Q20name.txt"

答案 5 :(得分:-3)

您应该可以使用插入符号(^)to escape a percent sign

编者注:链接已经死了;两种方式:%本身逃脱%,但仅在批处理文件中,而不是在命令提示符下; ^ 从不转义%,但在命令提示符下可以使用间接来阻止变量扩展,仅未加引号字符串。

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