stakowerflol
stakowerflol

Reputation: 1079

How to set a variable in cmd which is a string from powershell command result?

I want to store the result of powershell command in cmd variable as String : powershell -com "(ls | select -Last 1).FullName". How to do this?

Upvotes: 1

Views: 4619

Answers (3)

lit
lit

Reputation: 16266

A FOR loop can provide the path to the file. If the default directory sorting order is not the result needed, specify additional command line switches on the DIR command.

FOR /F "delims=" %F IN ('DIR /B') DO (SET "THE_FILE=%~fF")
ECHO THE_FILE is "%THE_FILE%"

In a .bat file script, double the percent characters on FOR loop variables.

FOR /F "delims=" %%F IN ('DIR /B') DO (SET "THE_FILE=%%~fF")
ECHO THE_FILE is "%THE_FILE%"

The .bat file scripts can also run PowerShell scripts. It is best practice to not use aliases such as ls in scripts.

FOR /F "delims=" %%F IN ('powershell -NoLogo -NoProfile -Command ^
    "(Get-ChildItem -File | Select-Object -Last 1).FullName"') DO (SET "THE_FILE=%%~fF")
ECHO THE_FILE is "%THE_FILE%"

Upvotes: 1

Ben Personick
Ben Personick

Reputation: 3264

The problem with cmd here is that I want to get the full paths for FOLDERs NOT recursive... this dir /ad /b doesn't give full paths and this dir /ad /b /s does it recursively... – stakowerflol 2 hours ago

That's not a problem, you can return the full file path without recursing.

If you are changing directory to the path you need to check then it's stored in %CD%

If you need the path to whee the Script itself is it's stored in %~dp0

If you want to provide an argument to specify and arbitrary path and get all of the listings it will be that argument term (EG %~1)

With all three possible options you can do the same thing:

Either

Prepend the provided variable to the output of the chosen directory enumeration method

OR

Use a For loop to get the file names at that path and show the result with the full path.

IE

Jenkins_A_Dir.bat

@(
  SETLOCAL
  ECHO OFF
  SET "_Last="
  ECHO.%~1 | FIND /I ":\" > NUL && (
   SET "_CheckHere=%~1"
  )
  IF NOT DEFINED _CheckHere (
    SET "_CheckHere=C:\Default\Path\When\No Argument\Specified"
  )
)

REM Use a For loop to get everything in one variable

FOR %%A IN (
  "%_CheckHere%\*"
) DO (
  SET "_Last=%%A"
)
ECHO.Found "%_Last%"


REM Use `FOR /F` with DIR, and append the path to Check:

SET "_Last="
FOR /F "Tokens=*" %%A IN ('
  DIR /A-D /B "%_CheckHere%\*"
') DO (
  SET "_Last=%_CheckHere%\%%A"
)
ECHO.Found "%_Last%"

Of course you don't NEED to have set a variable such as _CheckHere

Instead, you can just replace all of the instances of %_CheckHere% with `%~1 instead, that would work just fine in the above examples too.

Okay, what if you just wanted to check the location the script was running in.

Then either change the above to use SET "_CheckHere=%~dp0" or Replace %_CheckHere% with %~dp0 throughout.

Okay but what if you don't want to set a variable you want to it to use the current working directory.

When then, even easier:

Jenkins_Current_Dir.bat

@(
  SETLOCAL
  ECHO OFF
  SET "_Last="
)

REM Use a For loop to get everything in one variable

FOR %%A IN (
  "*"
) DO (
  SET "_Last=%%~fA"
)
ECHO.Found "%_Last%"


REM Use `FOR /F` with DIR, and let it append the current working directory to the path:

SET "_Last="
FOR /F "Tokens=*" %%A IN ('
  DIR /A-D /B "*"
') DO (
  SET "_Last=%%~fA"
)
ECHO.Found "%_Last%"

Upvotes: 0

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200483

CMD does not have a straightforward way of assigning command output to a variable. If the command produces just a single line you could use a for loop

for /f "delims=" %a in ('some_command /to /run') do @set "var=%a"

However, if the command produces multiple lines that will capture only the last line. A better approach would be redirecting the output of the command to a file and then reading that file into a variable:

set "tempfile=C:\temp\out.txt"
>"%tempfile%" some_command /to /run
set /p var=<"%tempfile%"
del /q "%tempfile%"

If you literally need only the last file in a directory you don't need to run PowerShell, though. That much CMD can do by itself:

for /f "delims=" %f in ('dir /a-d /b') do @set "var=%~ff"

Beware that you need to double the % characters when running this from a batch file.

Upvotes: 3

Related Questions