如何处理逼近路径名括号在for循环中? [英] How to handle closing parenthesis in path names in a for loop?

查看:104
本文介绍了如何处理逼近路径名括号在for循环中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我还有很长的路径名的程序,我必须在FOR / F回路,其中包括一个右括号),并从其中我需要解析输出运行:

I have a long path name to a program I must run in a for /f loop, which includes a closing parenthesis ")", and from which I need to parse the output:

for /f "tokens=1" %%G in ('"C:\Documents and Settings\myaccount\Desktop\Test_release (x86)\program.exe" list') do (echo Will do something with %%G)

...其中'名单'是传递给我的程序的参数。我得到的错误'C:\\文件'。不被识别为一个内部或外部命令,可操作的程序或批处理文件

...where 'list' is a parameter passed to my program. I get the error "'C:\Documents' is not recognized as an internal or external command, operable program or batch file."

我知道的问题是,其实右括号关闭为块,所以结束双引号是不是看到,所以长路径名未在双封闭报价了。我不明白的是为什么的是这种情况发生,因为我的路径双引号括起来?我也试过有usebackq选项:

I do know the problem is that the closing parenthesis in fact closes the "for" block, so the ending double quotes is not "seen", so the long path name is not enclosed within double quotes anymore. What I don't understand is why is this happening, since my path is enclosed within double quotes? I also tried the usebackq option:

for /f "usebackq tokens=1" %%G in (`"C:\Documents and Settings\myaccount\Desktop\Test_release (x86)\program.exe" list`) do (echo Will do something with %%G)

...没有更好的效果。我试图逃跑像这样^)或类似这种^^)无关。尝试加倍双引号:

...with no better results. I tried to escape like this "^)" or like this "^^)", nothing to do. Tried doubling the double quotes:

for /f "tokens=1" %%G in ('""C:\Documents and Settings\myaccount\Desktop\Test_release (x86)\program.exe"" list') do (echo Will do something with %%G)

还不行。

我,而且,在使用保存的路径,这是不是事先知道(从CD%建造%)的变量,事实上 EnableDelayedExpansion 被激活。我试图延迟扩展(这并固定在其他情况类似的问题),以prevent变量的扩张在读取时间以及执行时拖延:

I'm, furthermore, in fact using a variable that holds the path, which is not know in advance (built from %CD%), and EnableDelayedExpansion is activated. I tried the delayed expansion (which did fixed similar problems in other situations) to prevent the variable's expansion at read time and delay it at execution time:

setlocal EnableDelayedExpansion
set _var=%CD%\program.exe
@REM _var now contains C:\Documents and Settings\myaccount\Desktop\Test_release (x86)\program.exe
for /f "tokens=1" %%G in ('"!_var!" list') do (echo %%G)
endlocal

还不行,不明白为什么。

Still doesn't work, don't understand why.

但是,在上述code延迟扩展的双引号加倍:

But, doubling the double quotes with delayed expansion in above code:

for /f "tokens=1" %%G in ('""!_var!"" list') do (echo %%G)

确实工作! ...为什么...为什么有做到这一点?它有什么样的影响?我听不懂。我还担心它可能会在某些特殊情况导致一个问题...

does work!... why... why having to do this??? What effect does it have? I don't understand. I also fear it may cause a problem in some specific circumstances...

任何想法?

推荐答案

在回答这个问题的评论表示XP提供了不同的行为,则新的Windows版本。

Comments in the answers to this question indicate XP gives different behavior then newer Windows versions.

有一个众所周知的在XP /˚F错误:的http:/ /www.dostips.com/forum/viewtopic.php?p=9062#p9062 。但这个问题不与该错误。

There is a known FOR /F bug in XP: http://www.dostips.com/forum/viewtopic.php?p=9062#p9062. But this problem is not related to that bug.

的实际问题,从如何FOR / F的IN()子句中执行命令造成的。它采用 CMD \\ C命令(见<一href=\"http://stackoverflow.com/questions/4094699/how-does-the-windows-command-inter$p$pter-cmd-exe-parse-scripts/4095133#4095133\">How不Windows命令国米preTER(CMD.EXE)解析脚本?)

The actual problem stems from how FOR /F executes a command in the IN() clause. It uses CMD \C command (See How does the Windows Command Interpreter (CMD.EXE) parse scripts?)

您可以通过添加这一行Aacini的PROG.BAT例如观察此行为。

You can observe this behavior by adding this line to Aacini's PROG.BAT example.

echo cmdcmdline=%cmdcmdline%

下一个问题涉及如何CMD论述出现在/ C命令,以及为什么XP行为与最近的Windows版本不同。报价

The next issue deals with how CMD deals with quotes that appear in the /C command, and why XP behaves differently than more recent Windows versions.

这个命令在XP中失败,但在Vista和超越成功:

This command fails in XP, but succeeds in Vista and beyond:

for /f "delims=" %a in ('"test (this)\prog" args') do @echo %a

对于尝试执行(%CMDCMDLINE%)的命令是两个版本(在不考虑COMSPEC%差别%)是相同的:

The command that FOR tries to execute (%cmdcmdline%) is the same in both versions (disregarding differences in %COMSPEC%):

C:\Windows\system32\cmd.exe /c "test (this)\prog" args

XP有它如何与报价有关系的CMD设计缺陷。该漏洞甚至是记录(但它不被识别为一个缺陷)。 Vista和超出部分修复设计缺陷,但也懒得纠正文档。

XP has a CMD design flaw in how it deals with the quotes. The flaw is even documented (but it is not recognized as a flaw). Vista and beyond partially fix the design flaw, but don't bother to correct the documentation.

下面是HELP CMD

Here is an excerpt from HELP CMD

If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line, where the following logic is
used to process quote (") characters:

    1.  If all of the following conditions are met, then quote characters
        on the command line are preserved:

        - no /S switch
        - exactly two quote characters
        - no special characters between the two quote characters,
          where special is one of: &<>()@^|
        - there are one or more whitespace characters between the
          two quote characters
        - the string between the two quote characters is the name
          of an executable file.

    2.  Otherwise, old behavior is to see if the first character is
        a quote character and if so, strip the leading character and
        remove the last quote character on the command line, preserving
        any text after the last quote character.

我们希望CMD遵循规则1,这样的报价是preserved,但侵犯在XP中的特殊字符的限制,所以规则2之后和CMD试图执行

We want CMD to follow rule 1 so that quotes are preserved, but ( and ) violate the special character constraint on XP, so rule 2 is followed and the CMD tries to execute

test (this)\prog args

这应该是相当明显的,为什么失败!

It should be fairly obvious why this fails!

我想不出任何理由的特殊字符的限制存在于规则1.它违背了什么MS试图做的全部目的。

I can't think of any reason why the special character constraint exists in rule 1. It defeats the whole purpose of what MS is attempting to do.

显然,设计缺陷部分固定在Vista和超越,但他们并没有更新的帮助文档。 Vista的忽略特殊字符和使用规则1处理命令,报价是preserved,和一切正常。

Apparently the design flaw is partially fixed in Vista and beyond, but they haven't updated the HELP documentation. Vista ignores the special characters ( and ) and processes the command using rule 1, the quotes are preserved, and everything works.

更新2015年5月17日: 不幸的是,Vista和超越还是把 @ ^ &安培; 特殊字符,即使它们的文件名中的有效字符。当然,&LT; &GT; | 是视为特殊字符,但他们不是在文件名有效反正。因此,对于Vista和超越,对于规则1的文档应该阅读,其中特别是下列之一:&功放;&LT;&GT; @ ^ |

Update 2015-05-17: Unfortunately, Vista and beyond still treat @, ^, and & as special characters, even though they are valid characters within file names. Of course <, >, and | are treated as special characters, but they are not valid in a file name anyway. So for Vista and beyond, the documentation for rule 1 should read where special is one of: &<>@^|.

我一直追溯到每个人都有记录的行为,它是所有与上述一致。

I've traced the behavior that everyone has documented, and it is all consistent with the above.

有是不使用延迟的扩展变量来执行在XP的命令的方式,它是与Vista和超越兼容

There is a way to execute the command on XP without using a delayed expansion variable, and it is compatible with Vista and beyond.

for /f "delims=" %a in ('^""test (this)\prog" args^"') do @echo %a

打开和关闭引号逃脱,使不与干预FOR解析器。即对于IN()子句执行的命令是

The opening and closing quotes are escaped so that the ) does not interfere with the FOR parser. The command that is executed for the IN() clause is

C:\Windows\system32\cmd.exe /c ""test (this)\prog" args"

XP和Vista中遵循规则2,因为有两个以上的报价,所以CMD执行时

Both XP and Vista follow rule 2 because there is more than two quotes, so CMD executes

"test (this)\prog" args

和一切正常!

这个答案的其余部分是过时,而且preserved给上下文现有注释。

The rest of this answer is outdated but preserved to give context to existing comments.

您非常1 code例如应该工作;它不能的(做不应该)的给你描述的错误消息。该错误消息脱落在第一个空间,这意味着该路径未引用或逃脱的路径。但你是肯定,它被引述。

Your very 1st code example should work; it cannot (make that should not) give the error message you describe. The error message breaks off the path at the first space, which implies that the path was not quoted or escaped. But you are "sure" it was quoted.

这个问题的关键是三条信息靠近你的帖子的末尾:

The key to the problem is three pieces of information near the end of your post:


  1. 您是的实际的使用可变延迟扩展

这不起作用: FOR / F标记= 1%%的G('!_var名单)做(回声%% G)

这个作品: FOR / F标记= 1%%的G('!_var名单),做(回声%% G)

如果变量的值已经报价,你会得到你所描述的行为。

If the value of var is already quoted, you will get the behavior you are describing.

您var的值必须是C:\\ Documents和Settings \\我的账户\\桌面\\ Test_release(x86)的\\ Program.exe文件。,包括引号

The value of your var must be "C:\Documents and Settings\myaccount\Desktop\Test_release (x86)\program.exe", including the quotes.

为了使这个解释更具有可读性,我将缩短路径测试(这)\\ prog.exe

To make this explanation more readable I will shorten the path to "test (this)\prog.exe"

!VAR!失败,因为它扩展到,测试(本)\\ prog.exe,这有效地unquotes的路径。串具有三个区域,两块引用,一个在不是中间

"!var!" fails because it expands to ""test (this)\prog.exe"", which effectively unquotes the path. The string has three areas, two that are quoted, and one in the middle that is not:

引用空区不带引号的路径引用空区

!VAR!的作品,因为它扩展到测试(这)\\ prog.exe和路径现在再次引用。现在有五个方面的字符串中:

""!var!"" works because it expands to """test (this)\prog.exe""" and the path is now quoted again. There are now five areas within the string:

引用空区未加引号的空区引用路径未加引号的空区引用空区

"empty quoted area"empty unquoted area"quoted path"empty unquoted area"empty quoted area"

简单的答案,你应该如何进行:

The simple answer as to how you should proceed:

如果变量的值已经报价,然后只需使用 VAR 编辑 - 这并不在XP上运行:!!!变种!工作在两个

If the value of var is already quoted, then simply use !var! Edit- that doesn't work on XP: "!var!" works on both

如果变量的值不是引用,然后用VAR! 编辑 - 这并不在XP上运行: !VAR!工作在两个

If the value of var is not quoted, then use "!var!" Edit- that doesn't work on XP: ""!var!"" works on both

这篇关于如何处理逼近路径名括号在for循环中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆