2016-11-13 55 views
0

引述长filenamed命令在for循环中链接的批处理文件

Best free resource for learning advanced batch-file usage?

Dealing with quotes in Windows batch scripts

这似乎是那些发疯报价问题之一。在这个示例程序中:

@echo off 
set wmicpath=%windir%\System32\wbem\wmic.exe 

for /f "usebackq" %%a in (`%wmicpath% COMPUTERSYSTEM GET SystemType ^| findstr /I "x64"`) do (
    echo %%a 
) 

该程序运行得很好。除非你试图引用wmicpath。想象一下,如果你会认为它包含一个长路径名称。那么你应该引用它。但我无法完成它的工作。这种失败:

for /f "usebackq" %%a in (`"%wmicpath%" COMPUTERSYSTEM GET SystemType ^| findstr /I "x64"`) do (

但这个工程!:

for /f "usebackq" %%a in (`"%wmicpath%" COMPUTERSYSTEM GET SystemType ^| findstr /I x64`) do (

为做到这一点:

for /f "usebackq" %%a in (`"%wmicpath%" COMPUTERSYSTEM GET SystemType`) do (

有一些非常奇怪的有关在为命令匹配报价。只要你不在别处开始引用,你可以引用命令...

这可能吗?我试图在不同的点逃脱,但我不知道什么时候行情所涉及的转义规则...

编辑:我觉得这个环节可能是问题(即:这是一个错误):Pipe in for loop breaks double quoted variables

回答

2
@echo off 
    setlocal enableextensions disabledelayedexpansion 
    set "wmicpath=%windir%\System32\wbem\wmic.exe" 

    for /f "usebackq delims=" %%a in (` 
     ^""%wmicpath%" COMPUTERSYSTEM GET SystemType ^| findstr /I "x64"^" 
    `) do (
     echo %%a 
    ) 

如果你看一下开始和内部命令的结束,你会看到两个额外的^"(一逃脱双引号)。您的问题是for命令生成一个单独的实例cmd来处理内部命令,并且这个单独的实例将删除最初和最后一个双引号。

为什么要逃脱报价?为了避免这些额外的引号与命令中的双引号配对,这可能导致其他一些解析问题。

您可以运行cmd /?获取帮助页面(对不起,我有一个西班牙语语言环境,所以我不会在这里包括输出)。您会看到一段关于/C/K的用法,解释了引用移除行为。

+0

非常好!谢谢。我在昨天凌晨1点左右就想出了我自己,但不知道究竟为什么或在哪里记录了它(如果有的话)。我认为这是一个错误,但正如你所说,它与最初和最后的双引号相匹配。 – carveone

0
>x64.txt ECHO x64 

for /f "usebackq" %%a in (`"%wmicpath%" COMPUTERSYSTEM GET SystemType ^| findstr /I /g:x64.txt`) do (

可能是一种解决方法,具体取决于您的实际应用和偏好。

+0

findstr在这方面非常灵活,但通常我会避免创建外部文件。 – carveone

1

首先,我会改变命令,WMIC允许你使用查询语言LIKE运算符,在这种情况下可以删除管道任何东西的需要。

@Echo Off 
Set "WMIC=%SystemRoot%\System32\Wbem\wmic.exe" 
For /F "UseBackQ Skip=1" %%a In (
    `""%WMIC%" ComputerSystem Where "SystemType Like 'x64%%'" Get SystemType"` 
) Do For %%b In (%%a) Do Echo=%%b 
Timeout -1 

然后我可能甚至改变命令,使得我不使用反引号的格式。

@Echo Off 
Set "WMIC=%SystemRoot%\System32\Wbem\wmic.exe" 
For /F "Skip=1" %%a In (
    '""%WMIC%" ComputerSystem Where (SystemType Like "x64%%") Get SystemType"' 
) Do For %%b In (%%a) Do Echo=%%b 
Timeout -1 

虽然这并不直接回答主旨题的问题,它允许您的特定命令才能正常工作。

但既不是必要的,您的特定命令的例子,因为你并不需要在for循环呼应的是输出:

@Echo Off 
Set "WMIC=%SystemRoot%\System32\Wbem\wmic.exe" 
"%WMIC%" ComputerSystem Get SystemType|Find /I "x64" 
Timeout -1 

更改查找FINDSTR如果你觉得有必要。

+0

你是对的WMIC。做得很好。我猜如果我以某种方式做某件事情,即使效率不高,我仍然会这样做。我认为他们称之为懒惰:-)你对我的例子是正确的,但在我的实际代码中,我存储输出并进一步使用它。 – carveone

+1

我接受你可能是这样做的,但是,据我所知,只有根据你的问题选择的命令才能输出以下内容,并找到标准'x64-based'。出于这个原因,你可以使用'&&'后面的例子来设置成功。 '“%WMIC%”ComputerSystem Get SystemType | Find/I“x64”> Nul &&(Set var = x64-based)'。 – Compo