Home > OS >  get path from the command line using windows batch
get path from the command line using windows batch

Time:10-07

I would like to get the path after -h option. Are there some commands that can be helpful for this case?

Input (which is actually in my case the output of the following command - 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  

Desired output:

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

CodePudding user response:

Assuming this command line is in variable input:

This works on the command line, to test the approach:

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

And this is your code for a batch file (reading from %input% and saving into %result%):

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

This works by first cutting everything until the -h in a variable string replacement expression and then using for /f with the " as delimiter. In order to be able to specify the " as delimiter, we can't enclose the delims=... tokens=... part in quotes as we'd normally do, instead we have to escape every individual character with special meaning (including the space) with ^.

Note: This assumes that the path will always be quoted in the command line. If it isn't, you'd need to first check if the part after cutting the left side starts with a quote and then either use the quote or the space as delimiter accordingly:

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%

...but having to resort to this sort of unreadable trickery seriously makes me wonder whether it even makes sense to use batch files with decades of legacy for this. Did you consider using PowerShell or Python or some other proper scripting language instead?

CodePudding user response:

Given that the target command line does not contain wildcards * and ? as well as < and >, the following approach should do it:

  • At first, wrap a for /F loop around to capture the output of wmic (without ProcessID since it is anyway not used, and using option /VALUE to avoid trailing spaces), then nest another for /F that processes that text strings again (this is necessary to correctly deal with the Unicode output of wmic).
  • Then use a standard for loop to walk through the parts/arguments of the command line, check against -h and retrieve the subsequent (quoted or unquoted) item.
  • Eventually skip the remaining command line portion.

This is a possible (untested) implementation:

@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%"
  • Related