【问题标题】:get path from the command line using windows batch使用 Windows 批处理从命令行获取路径
【发布时间】:2021-10-07 12:23:41
【问题描述】:

我想在 -h 选项之后获取路径。 是否有一些命令对这种情况有帮助?

输入(在我的情况下实际上是以下命令的输出 - wmic process where "name like '%%w3wp%%'" get processid,commandline):

c:\windows\system32\inetsrv\w3wp.exe -ap "SharePoint Central Administration v4" -v "v4.0" -l "webengine4.dll" -a \\.\pipe\iisipm23e2eb4d-e657-4192-980c-9ac9147d2f75 -h "C:\inetpub\temp\apppools\SharePoint Central Administration v4\SharePoint Central Administration v4.config" -w "" -m 0  5144  

期望的输出:

"C:\inetpub\temp\apppools\SharePoint Central Administration v4\SharePoint Central Administration v4.config"

【问题讨论】:

  • 你试过什么?目标路径是否总是被引用?命令行是否可以包含诸如*? 之类的通配符?

标签: windows batch-file cmd


【解决方案1】:

鉴于目标命令行不包含wildcards*?以及<>,以下方法应该可以做到:

  • 首先,将for /F loop 包裹起来以捕获wmic 的输出(没有ProcessID,因为它无论如何都没有使用,并使用选项/VALUE 以避免尾随空格),然后嵌套另一个for /F再次处理该文本字符串(这是正确处理 wmic 的 Unicode 输出所必需的)。
  • 然后使用standard for loop 遍历命令行的部分/参数,检查-h 并检索后续(引用或未引用)项。
  • 最终跳过剩余的命令行部分。

这是一个可能的实现:

@echo off
rem // Capture the output of `wmic` using two `for /F` loops for proper Unicode-to-ASCII/ANSI conversion:
for /F "delims=" %%I in ('
    wmic Process where "Name like '%%w3wp%%'" get CommandLine /VALUE
') do for /F "tokens=1* delims==" %%J in ("%%I") do (
    rem // Reset flag, iterate through the parts of the retrieved command line:
    set "FLAG=" & for %%L in (%%K) do (
        rem // Check against option string `-h` (remove `/I` to become case-sensitive):
        if /I "%%~K"=="-h" (
            rem // Set a flag to indicate that next item is the target path:
            set "FLAG=#"
        ) else if defined FLAG (
            rem // Flag is set, hence extract unquoted target path and terminate loop:
            set "TARGET=%%~K"
            goto :NEXT
        )
    )
)
:NEXT
echo Extracted path: "%TARGET%"

【讨论】:

    【解决方案2】:

    假设这个命令行在变量input中:

    这适用于命令行,以测试该方法:

    for /f delims^=^"^ tokens^=1 %a in ('echo %input:*-h =%') do @echo %a
    

    这是您的批处理文件代码(从%input% 读取并保存到%result%):

    for /f delims^=^"^ tokens^=1 %%a in ('echo %input:*-h =%') do @set result=%%a
    echo %result%
    

    首先在变量字符串替换表达式中剪切所有内容直到-h ,然后使用for /f" 作为分隔符。为了能够将" 指定为分隔符,我们不能像通常那样将delims=... tokens=... 部分括在引号中,而是我们必须转义每个具有特殊含义的单个字符(包括空格) ^.

    注意:这假定路径将始终在命令行中被引用。如果不是,您需要先检查左侧切割后的部分是否以引号开头,然后相应地使用引号或空格作为分隔符:

    set x=%input:*-h =%
    if ^%x:~0,1% equ ^" (
      for /f delims^=^"^ tokens^=1 %%a in ('echo %x%') do @set result=%%a
    ) else (
      for /f tokens^=1 %%a in ('echo %x%') do @set result=%%a
    )
    echo %result%
    

    ...但是不得不严肃地诉诸这种难以理解的诡计让我想知道使用具有数十年历史的批处理文件是否有意义。您是否考虑过改用 PowerShell 或 Python 或其他合适的脚本语言?

    【讨论】:

      【解决方案3】:

      此方法假定所需的字符串以引号和空格结尾(在本例中,在-w 开关之前)。

      @echo off
      setlocal
      
      set "input=c:\windows\system32\inetsrv\w3wp.exe -ap "SharePoint Central Administration v4" -v "v4.0" -l "webengine4.dll" -a \\.\pipe\iisipm23e2eb4d-e657-4192-980c-9ac9147d2f75 -h "C:\inetpub\temp\apppools\SharePoint Central Administration v4\SharePoint Central Administration v4.config" -w "" -m 0  5144"
      
      set "x=%input:-h =" & set "part=%"
      set "output=%part:" =" & REM %"
      
      echo %output%
      

      您可以在thisthis 的答案中阅读有关该方法的进一步说明...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-14
        • 2011-04-19
        • 2012-02-28
        相关资源
        最近更新 更多