Save command output to variable - windows

In a batch file, I am trying to fetch the output of a command and save it to a variable.
The goal of my command is to count the number of folders in a certain folder.
I can't use the trick provided in this accepted answer because I would have to do cd path\to\my\folder to get to the current directory. Unfortunately, I can't do this command because path\to\my\folder is in fact a UNC path (\\path\to\my\folder), and cd \\some\UNC\path is not supported by the windows cmd.
I am aware of this answer but I don't want to use a temporary file.
So I tried to do the following:
To obtain the number of folders, I use:
dir \\path\to\my\folder | find /c "<REP>"
This works fine and returning me a number as I would expect.
To retrieve the output of this command in a batch variable, I tried:
FOR /F "TOKENS=*" %%i IN ('\\path\to\my\folder | find /c "<REP>"') DO
SET value = %%i
But without success, the error message being...
| was unexpected.
...when I execute the batch file and...
%%i was unexpected.
when I try to execute the command directly in a command window. I tried to escape the quotes around the <REP> string (...find /c ""<REP>""') DO...), got me the same error.
Am I on the right path to retrieve the output in a variable? What should I do to resolve the error message?
Or maybe there is a simpler way to set a command output in a variable?

You can use the answer you first mentioned. You don't have to cd there, but you can use pushd which will allocate a temporary drive letter for UNC paths which will be released when you do a popd.
So in essence:
pushd \\server\path
set count=0
for /d %%x in (*) do set /a count+=1
popd

Related

How to get the location of a file in a variable in a batch file?

Windows Command prompt Query:
I have a root directory "A".
There are several other sub-directories inside "A".
Now somewhere inside these directories there is a file called "setup.exe".
Now I want the complete path from A till the file.
I will need this path later in my batch file.
So I want it to be stored in some variable.
I have found ways to get the path but not able to store it to some variable.
Kindly help.
Try this,it may help you.
for /r "C:\directory path" %%a in (*) do if "%%~nxa"=="setup.exe" set variable_to_store_path=%%~dpnxa
if defined variable_to_store_path (
echo %variable_to_store_path%
) else (
echo File not found
)
Let command DIR find setup.exe in directory tree and use command FOR to process the output of DIR to assign the found setup.exe with full path to an environment variable.
#echo off
set "SetupFile="
for /F "delims=" %%# in ('dir C:\a\setup.exe /A-D /B /S 2^>nul') do set "SetupFile=%%#"
if "%SetupFile%" == "" (
echo Could not find setup.exe.
) else (
echo Found %SetupFile%
)
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
dir /?
for /?
if /?
set /?
See also Using command redirection operators to understand suppressing the error message of command DIR output to STDOUT on not finding any setup.exe by redirecting the error message to device NUL with 2>nul with escaping redirection operator > with ^ to be applied on execution of command DIR instead of producing a syntax error because a redirection specified within set / command / file specification of command FOR is not possible.

windows cmd enabledelayedexpansion not working

I'm having trouble running !var! examples ad described here http://ss64.com/nt/delayedexpansion.html
Instead of the expected variable content output as the example describes, I get the literal "bang V A R bang" output, any idea?
C:\>Setlocal EnableDelayedExpansion
C:\>Set _var=first
C:\>Set _var=second& Echo %_var% !_var!
first !_var!
thanks.
You are getting an unexpected result because you are issuing the commands at the command prompt. Create a batch file by putting the following commands in a file with a .bat extension then run the batch file.
#echo off
Setlocal EnableDelayedExpansion
Set _var=first
Set _var=second& Echo %_var% !_var!
E.g., if I created a batch file named delayedexp.bat with the above contents, I would see the following when I run it:
C:\Users\JDoe\Documents\>delayedexp
first second
setlocal only works within the confines of a command script:
help setlocal
If you have access to the parameters of the cmd call, you can set parameter /v. Must be first. And use ! instead % for variables.
%windir%\system32\cmd.exe /v /c set a=10&echo a=!a!&echo My Path is %CD%&pause
This is how, for example, you can get the date in the Russia-France format directly in the Windows shortcut, where a simple percentage is impossible due to its doubling. In std queries with the /v parameter, both a percentage and an exclamation mark will work fine, but single % for cicles.
%windir%\system32\cmd.exe /v /c echo off&for /F "tokens=1-6 delims=:., " %A In ("!date! !time!") Do (Echo %A.%B.%C %D:%E:%F)&pause

Remove unwanted path name from %path% variable via batch

Scope: Windows XP or newer
Tools: Batch script
I need to be able to remove an unneeded path name from the system %PATH% variable. I know how to add a new path name to the system %PATH% variable, using a tool such as SETX.EXE, which also makes it immediately available within the existing CMD environment. It's probably a matter of using FIND and/or a FOR loop of some kind, but I'm not quite sure how to accomplish this. Here's a sample path statement...
%PATH% = C:\;C:\Program Files\Common Files\Java;C:\oracle\product\10.2.0\bin;C:\WINDOWS;C:\WINDOWS\system32;
From this, I need to be able to remove the full path name related to "oracle." So, in the above example, I need to be able to remove the "C:\oracle\product\10.2.0\bin" from the above path statement. Unfortunately, not only could the oracle path name be different than shown above, there could be multiple oracle path names and all need to be removed. I tried implementing the solution here...
How can I extract a full path from the PATH environment variable?
However, it just isn't working. The script wouldn't find the path name. Any help would be appreciated. Thank you.
This removes the substring C:\Program Files (x86)\Git\bin; from the PATH string and re-assigns:
set PATH=%PATH:C:\Program Files (x86)\Git\bin;=%
You might use this to see the change:
echo %PATH:C:\Program Files (x86)\Git\bin;=% | tr ; \n
Note: be exact on the substring. It's case-sensitive and slash-sensitive.
If you need to make it a persistent change use setx instead of set and open another console for changes to take effect.
setx /M PATH "%PATH:C:\Program Files (x86)\Git\bin;=%"
You can try something like this :
#echo off&cls
setlocal EnableDelayedExpansion
set $line=%path%
set $line=%$line: =#%
set $line=%$line:;= %
for %%a in (%$line%) do echo %%a | find /i "oracle" || set $newpath=!$newpath!;%%a
set $newpath=!$newpath:#= !
echo set path=!$newpath:~1!
I putted an echo to the last line. Check the result and If it's OK for you, remove it.
After trying SachaDee's answers I got errors with paths like
C:\Program Files (x86)
with brackets:
Program Files (x86)\Directory
gave me
Directorywas unexpected at this time. (no matter what time I tried it)
I added
set $line=%$line:)=^^)%
before the for-loop and
set $newpath=!$newpath:^^=!
after the loop (not sure if it is necessary)
#echo off
setlocal EnableDelayedExpansion
set path
set $line=%path%
set $line=%$line: =#%
set $line=%$line:;= %
set $line=%$line:)=^^)%
for %%a in (%$line%) do echo %%a | find /i "oracle" || set $newpath=!$newpath!;%%a
set $newpath=!$newpath:#= !
set $newpath=!$newpath:^^=!
set path=!$newpath:~1!
And it is now working.
I found the other solutions to this problem a bit awkward, I don't really want to rely on exact paths, complex 'delayed expansion' syntax, removing spaces for the 'for /f' loop and then adding them back in...
I think this is more elegant, and I commented the hell out of it so even someone new to the horrors of Batch can follow along.
::Turn off command display and allows environmental variables to be overridden for the current session
#echo off & setlocal
::Creates a unique file to use for the 'for loop'
set "TMPFILE="%temp%\tmp%RANDOM%%RANDOM%.txt""
::Duplicate PATH into OLDPATH
set "OLDPATH=%PATH%"
::Declare label for the 'goto' command
:Loop
::Extract the first text token with the default delimiter of semicolon
for /f "tokens=1 delims=;" %%G in ("%OLDPATH%") do (
REM Copy text token to TMPFILE unless what we want to remove is found
<NUL set /p="%%G" | find /i "StRiNgThAtMaTcHeSwHaTtOrEmOvE" >NUL 2>&1 || <NUL set /p="%%G;" >>%TMPFILE%
REM Remove text token from OLDPATH
set "OLDPATH=%OLDPATH:*;=%"
)
::Repeat loop until OLDPATH no longer has any delimiters, and then add any remaining value to TMPFILE
echo %OLDPATH% | findstr /C:";" >NUL && (goto :Loop) || <NUL set /p="%OLDPATH%" >>%TMPFILE%
::Set the path to TMPFILE
for /f "usebackq delims=" %%G in (%TMPFILE%) do (set "PATH=%%G")
::Clean-up
del %TMPFILE% >NUL 2>&1
::An echo and pause just for debug purposes
echo %PATH%
pause
I use this in CYGWIN to filter out CYGWIN paths before starting some Windows commands:
export PATH=`perl -e '#a=grep {$_ =~ /^\/cygdrive\//} split(":", $ENV{PATH});print join(":",#a)'`
I'm quite sure it's easy to adapt to Windows-native perl and bat files. Advantage: the flexible power of regular expressions.
I wanted to remove %LocalAppData%\Microsoft\WindowsApps; from PATH. But this was not possible due to using a another variable in the environment variable for Windows. The CALL hack is worked in SS64. (Also, thanks to Jens A. Koch for the base command.)
CALL set PATH=%PATH:%LocalAppData%\Microsoft\WindowsApps;=%
Of course, the PATH changing by SET will not be permanent. For fixed change, it is necessary to use the SETX command or directly change the entries in the Registry.
Actually, this solution was not needed to delete %LocalAppData%\Microsoft\WindowsApps; from PATH.
The %LocalAppData%\Microsoft\WindowsApps; is stored in the PATH entry of the Registry's HKCU\Environment key. Although it is more practical to delete this entry with the REG DELETE command, if there are another directories in the PATH entry, they will also be deleted, so new solution is needed.
I failed to remove the %USERPROFILE% variable syntax from SET (The %% symbol dilemma). Fortunately, PShell came to the rescue:
SET userprofile=
Powershell -c "$UserEnvironmentPath = [System.Environment]::GetEnvironmentVariable('Path', 'User'); $UserEnvironmentPath = $UserEnvironmentPath.Replace('%USERPROFILE%\AppData\Local\Microsoft\WindowsApps;',''); [Microsoft.Win32.Registry]::SetValue('HKEY_CURRENT_USER\Environment', 'Path', $UserEnvironmentPath, [Microsoft.Win32.RegistryValueKind]::ExpandString)"
Special thanks to vonpryz for the last command. Because PowerShell's [System.Environment]::SetEnvironmentVariable command saves variables to Registry as REG_SZ even if their original value type is REG_EXPAND_SZ, which it's the known issue.
I wrote this code to simply remove any python executeable path from the path variable,
and insert my own specefic python version in the path so i can run python with
the versoin i wanted.
setlocal enableDelayedExpansion
set path`enter code here`
set $line=%path%
set $line=%$line: =#%
set $line=%$line:;= %
set $line=%$line:)=^^)%
set newpath=
for %%a in (%$line%) do (
echo %%a | find /i "python" ||set newpath=!newpath!;%%a
)
set path=!newpath!
set PATH=D:\python2.7\;%PATH%
#REM Rest of your script
python --version
#REM to exit the batch but not the window
exit /b
also, the first line is important! don't remove it or it wont work.
Notice: this code must run from a batch ".bat" file , if u want to copy paste this code in cmd window, you must replace all "%%a" to "%a" in this code.
If you know a file that exists within the directory you want to remove (e.g. want to remove all paths that might include java.exe), the following will work very straightforwardly by simply doing string replacement, no need to parse the path, etc:
#REM Executable to look for
set CMD=java.exe
:search
#REM Find the executable anywhere in the path
for %%a in (%CMD%) do set FOUND=%%~$PATH:a
if "%FOUND%"=="" goto done
#REM Strip \cmd.ext so we just have the directory
set FOUND=!FOUND:\%CMD%=!
#echo Found %CMD% in %FOUND%
#echo Removing %FOUND% from path...
set "PATH=!PATH:%FOUND%=!"
#REM Clean up any lone leftover \ in the path (in case the path was C:\foo\ instead of C:\foo)
set PATH=%PATH:;\;=;%
goto search
:done

List only path, file name and size in Windows command prompt

In Windows command prompt, I'm trying to list only path, file name and size, of all files including in a folder and its sub folders.
Like:
dir /s /b /a-d "C:\MainFolder\"
Problem is that I don't know how to show size of file. Is it possible?
From the command line:
for %F in ("c:\MainFolder\*") do #echo %~zF %F
Double up the percents if you use the command in a batch file.
Type HELP FOR or FOR /? from the command prompt for more information on the various values that are available with FOR variable expansion.
Try this command ---
for %%a in (*) do echo %%a

How do I find a directory in and store it into a variable, using a Windows batch file?

I need to find the location of a specific directory, and then store that directory path into a variable within a Windows batch script.
I also want the command to return when it finds a match (to avoid searching the entire hard drive once the directory has already been found).
So far I've tried this on the command line:
dir c:\ /s /b /ad | find "DirectoryName"
The problem with this is that it searches the entire drive, even after a match is found. Plus, I still can't figure out how to store the result in a variable within a batch file. There should only be a single result.
Basically I need the equivilent of somehting like this on Linux/bash:
export DIRPATH=`find / -name "DirectoryName" -print -quit`
Thanks for looking!
In batch you need FOR /F to get the output of a command.
FOR /F "usebackq delims=" %%p IN (`dir c:\ /s /b /ad ^| find "DirectoryName"`) DO (
set "DIRPATH=%%p"
)
echo %DIRPATH%
As there are quotes in the find command you need the usebackq-option.
And it's necessary to escape the pipe character one time, as it should pipe the dir command, not the for command

Resources