Assign content of DIR to a variable - windows

I wrote the following cmd
DIR /B "%appdata%\Mozilla\Firefox\Profiles"
which returns the following single folder which exists at that dir location
4jktnrk2.default
I wish to store 4jktnrk2.default in a variable.
I tried the following
SET A=DIR /B "%appdata%\Mozilla\Firefox\Profiles"
and
SET A="DIR /B %appdata%\Mozilla\Firefox\Profiles"
However neither of these work.
I also think its best to not use a FOR loop as there is only One folder in that directory.

#echo off
setlocal enableDelayedExpansion
set "dir_c="
for /f "delims=" %%a in ('DIR /B "%appdata%\Mozilla\Firefox\Profiles"') do (
if "!dir_c!" equ "" (
set "dir_c=%%~a"
) else (
set "dir_c=!dir_c!;%%~a"
)
)
echo %dir_c%
You have no other option but to use FOR /F.There's no unix style for assigning the result of command to variable in batch.

Excuse me. I think that the real goal of this request is to "Get a single folder in a variable". The code segment below do that:
for /D %%a in ("%appdata%\Mozilla\Firefox\Profiles\*") do set "A=%%a"
The natural way of process folders in a Batch file is via for /D command (the same way than the natural way to process files is via plain for command). The for /F ... in ('dir /B ... command is a less efficient method that is used just when for or for /D commands don't provide the required results.

You really should use FOR /D or FOR /F as Aacini and npocmaka have suggested.
If you insist that you don't want to use FOR, then you will have to resort to a temporary file:
dir /b "%appdata%\Mozilla\Firefox\Profiles" >folder.tmp
set /p "a=" <folder.tmp
del folder.tmp

Related

Replace "." to "_" in folders using CMD

As can be seen in the image I have folders with "." in them I would like to replace these with a "_" using CMD is there a method to do this.
cmd.exe shell scripting is the worst approach for anything more than #echo off :-)
But ok.
You can use the enhanced shell command set to replace characters in a variable:
set DUH=FBB
echo %DUH:B=O% -> FOO
So, for your problem, you need to read all folders and get them in a variable, so you can replace .=_ and then rename.
First batch: rena.cmd iterates over your folders
#echo off
for /D %%i in ( *.* ) do call rena2.cmd %%i
Second batch: rena2.cmd handles the rename
#echo off
setlocal enableextensions
setlocal enabledelayedexpansion
set TONAME=%~1
move %1 "%TONAME:.=_%"
exit /B
This can be done in one script, feel free to fiddle it together, I won't :-)
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir\t w o"
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%\*.*" '
) DO (
SET "dirname=%%a"
SET "dirname=!dirname:.=_!"
IF "!dirname!" neq "%%a" ECHO(REN "%sourcedir%\%%a" "!dirname!"
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(REN to REN to actually rename the files.
Dimply perform a directory-list, change the . to _ and if a change was made, perform the rename.

.bat - Create a menu from folder file list

I don't usually create .bat file, but I made this little script useful for develop.
I'm using this for reading and creating a list of files contained into a folder:
for /f "delims=|" %%f in ('dir /b C:\src\release\android\') do echo %%f
and I found this about how to create a menu starting from a list of file -> Multiple choices menu on batch file?
Now my question is:
I'd like to create a menu with a list of files contained into that folder which I can select (not multiple selection) by pressing it's relative number on the list, but i don't really know how to merge the two bit of code above.
The final result should work something like:
[1] ..
[2] ..
[3] ..
[4] ..
select file:
and it will install the selected file from the folder.
Any suggestion would be really appreciated.
Thanks in advance
This should work unless you're using a version of Windows that doesn't have choice, like if you're still on XP for some reason.
#echo off
setlocal enabledelayedexpansion
set count=0
set "choice_options="
for /F "delims=" %%A in ('dir /a:-d /b C:\src\release\android\') do (
REM Increment %count% here so that it doesn't get incremented later
set /a count+=1
REM Add the file name to the options array
set "options[!count!]=%%A"
REM Add the new option to the list of existing options
set choice_options=!choice_options!!count!
)
for /L %%A in (1,1,!count!) do echo [%%A]. !options[%%A]!
choice /c:!choice_options! /n /m "Enter a file to load: "
:: CHOICE selections get set to the system variable %errorlevel%
:: The whole thing is wrapped in quotes to handle file names with spaces in them
:: I'm using type because I'm not familiar with adb, but you be able to get the idea
type "C:\src\release\android\!options[%errorlevel%]!"
Improving upon SomethingDark's script to run Python scripts in a user's Document folder (I know, not best practice here for brevity's sake), as it currently wouldn't work when there are more than 10 choices:
#echo off
setlocal enabledelayedexpansion
set count=0
set "choice_options="
for /F "delims=" %%A in ('dir /a:-d /b C:\Users\JohnSmith\Documents\*.py') do (
REM Increment %count% here so that it doesn't get incremented later
set /a count+=1
REM Add the file name to the options array
set "options[!count!]=%%A"
)
for /L %%A in (1,1,!count!) do echo [%%A]. !options[%%A]!
::prompts user input
set /p filechoice="Enter a file to load: "
:: Location of python.exe and location of python script explicitly stated
echo Running !options[%filechoice%]!...
"C:\Users\JohnSmith\AppData\Local\Microsoft\WindowsApps\python.exe" "C:\Users\JohnSmith\Documents\!options[%filechoice%]!"

Windows Batch: getting Path without Shortening

I searched now for several Hours and didnt find any fitting solution for me.
When I try to get the current Path of the Batch File, I use normaly %~dp0.
This will leads in Paths like: D:\VM\TUTORI~2\STARTS~1.BAT
However this is not an issue, if only doing File Management, but I want to use the Script to call Vagrant commands.
It happens that the Vagrant System doesnt like this shortened Paths.
As soon as the Path is short enough or when I call it from the CMD directly, it works just fine.
I'm now searching for a way to get any unshortened Path to my working Directory.
But whatever I tried so far didnt work and google only delivers me how people Shorten their Paths.
Is there a practical Solution to this Problem?
I want to set a Variable in my Script looking like this:
D:\VM\tutorialtest
EDIT:
According to the Accepted Answer the working snippet for me is the Snippet without the "-2" on the 2. For Loop. This will give me the Path no matter where the folder is.
setlocal EnableDelayedExpansion
set myPath=%~DP0
set myPath=%myPath:*\=%
set fullPath=
pushd \
for %%a in ("%myPath:\=" "%") do (
set thisDir=%%~a
for /D %%d in ("!thisDir:~0!*") do (
set fullPath=!fullPath!\%%d
cd %%d
)
)
popd
echo Full path: %~D0%fullPath%
Result:
D:\VM\tutorialtest
Try this:
#echo off
setlocal EnableDelayedExpansion
set "myPath=%~DP0"
set "myPath=%myPath:*\=%"
set "fullPath="
pushd \
for %%a in ("%myPath:\=" "%") do (
set "thisDir=%%~a"
for /D %%d in ("!thisDir:~0,-2!*") do (
set "fullPath=!fullPath!\%%d"
cd "%%d"
)
)
popd
echo Full path: %~D0%fullPath%
Post the result, please.
EDIT: Bug fixed
The problem is that names that have less than 2 characters are cutted! (my mistake).
I did some testing and it seems that for /D %%d in ("TUTORI~2*") ... also returns the full name of the folder, so thisDir variable is not required. You may modify the for %%a loop this way and get the same result:
for %%a in ("%myPath:\=" "%") do (
for /D %%d in ("%%~a*") do (
set fullPath=!fullPath!\%%d
cd %%d
)
)
Edit - Corrected the code which can work with path with or without spaces.
for /f "delims=" %i in ('dir ^| findstr /i /c:"Directory of"') do set mypath=%i
set mypath=%mypath: Directory of =%
Above codes will work if you type them directly in command console, if you want to use it in batch file use it as below.
for /f "delims=" %%i in ('dir ^| findstr /i /c:"Directory of"') do set mypath=%%i
set mypath=%mypath: Directory of =%
I believe you are in need of getting the current working directory(something like pwd in Unix). 'dir' command usually returns the current path details along with variuos other details. We just pick the line with the directory name (line with the tag "Directory of") and then in the second line we remove the tag "Directory of" (replacing it with none).
Refer the below link for more string manipulation techniques.
http://www.dostips.com/DtTipsStringManipulation.php
Sample output - typed on command console
C:\test\new folder>for /f "delims=" %i in ('dir ^| findstr /i /c:"Directory of"') do set mypath=%i
C:\test\new folder>set mypath= Directory of C:\test\new folder
C:\test\new folder>set mypath=%mypath: Directory of =%
C:\test\new folder>echo.%mypath%
Did you try :
set $path=%cd%
echo %$path%
If this behaviour occurs when you open a cmd window, then type echo %comspec% at the cmd prompt and see what it returns: if it has command.com as part of it then it has been altered.
Another possibility is that the shortcut you are using to open a cmd window has command.com in the properties to launch it.
If you are using a shortcut then try to open a cmd prompt from the Win+R hotkey and type cmd and enter. See if this behaviour has changed but also check the first point above once more.

Recursive directory processing in a BAT file with a twist

OK, I apologize ahead of time for a) using an old, crappy technology (BAT files) and b) asking what seems to be a redundant question. I'm limited in the technology I'm allowed to use in this particular case and after looking at dozens of posts on the subject I can't find anything I can adapt to what I need.
I have a directory structure that looks like this:
A
B
C
D
etc...
XYZ
more folders
My BAT file is located outside this files system. I need to inspect it starting at level "C" and need to find the "XYZ" directory. The folders between C and XYZ can have variable names depending on the environment in which the files were created. I need to end up with a string that consists of the directory names from C through XYZ (i.e. "C\D\E\F....\XYZ") that I can put into a variable so when my BAT file is completed I can reference the variable and run another command.
I've looked at posts using FIND and FOR but I can't seem to figure out how to a) limit the string to the starting directory (for example when I combine FOR with DIR I get "A\B\C...") and how to stop when I get to "XYZ"...
Any help is greatly appreciated.
This should work in most situations:
#echo off
setlocal enableDelayedExpansion
set "root=c:\a\b\c"
set "target=xyz"
for %%R in ("%root%") do for /f "delims=" %%F in (
'dir /b /s /ad "%root%\%target%"'
) do (
set "fullPath=%%F"
set "relpath=!fullPath:%%~dpR=!"
)
echo !relpath!
It can fail if any of your paths contain ! or =. There are solutions for this, but the code is significantly more complicated.
EDIT
Actually, there is a relatively simple solution using FORFILES that should work in all situations. (Assuming your version of Windows has FORFILES)
#echo off
setlocal disableDelayedExpansion
set "root=c:\a\b\c"
set "target=xyz"
for /f "delims=" %%F in (
'forfiles /p "%root%" /m "%target%" /s /c "cmd /c if #isdir==TRUE echo #relpath"'
) do set "relpath=%%~F"
for %%R in ("%root%") do set "relpath=%%~nxR%relpath:~1%"
echo %relpath%
The only restriction is the code has to change slightly if your result contains poison characters like &. In that case you need to add quotes to the final ECHO statement, or else enable delayed expansion at the end and use echo !relpath!
For a) question:
FOR /F "TOKENS=*" %%d IN ('DIR A\B\C\XYZ /S /AD /B') DO SET variable=%%d
For a) and b) question:
FOR /D /R "A\B\C" %%d IN (*.*) DO IF /I "%%~nxd"=="XYZ" (SET variable=%%d& GOTO :EOF)
but this will exit batch script, so you need:
... your batch code
CALL :GET_XYZ
... your batch code
GOTO :EOF
:GET_XYZ
FOR /D /R "A\B\C" %%d IN (*.*) DO IF /I "%%~nxd"=="XYZ" (SET variable=%%d& GOTO :EOF)
ECHO XYZ not found!
GOTO :EOF

Batch Script issue

for deleting files, I will be using the code below to remove the oldest file in the directory and run it every day. It came from the question of mine.
Applying to the original batch script:
SET BACKUPDIR=C:\PATH\TO\BACKUPS
FOR /F %%i IN ('DIR /B /O-D %BACKUPDIR%') DO SET OLDEST=%%i
DEL %BACKUPDIR%\%OLDEST%
Something such as that checks if the file amount is 21, if so delete the latest one:
SET BACKUPDIR=C:\test
SET countfiles = dir BACKUPDIR /b | find /v /c "::"
if countfiles > 21
FOR /F %%i IN ('DIR /B /O-D %BACKUPDIR%') DO SET OLDEST=%%i
DEL %BACKUPDIR%\%OLDEST%
EDIT: Sorry for forgetting the question, my attempt was failing, I would be greatful for any way to direct how to make it work.
first, it seems set does not like spaces between the variable and the = sign: if you put a space, the variable name will include a space. so you must remove the space to properly define the variable name.
plus, your syntax for capturing the output of the command into a variable is wrong. the only way i am aware of (after desperately searching stackoverflow for the answer) is to use a for loop trick to use a temporary variable (see this question for more details). actually, you also need to escape the pipe for the command to be parsed correctly.
then, when the variable tested in the if expression does not exists, the results is always true, so make sure the variable exists. by removing the space as said above, the name in the if expression will match your variable name, and the test will execute properly.
then you forgot to make a block around the 2 last commands. actually, you are testing if you have more than 21 files and compute the oldest if it is true, then you ALWAYS delete the oldest.
also, the greater than operator > may be understood as a redirection. you may need to use the GTR operator.
SET BACKUPDIR=C:\test
FOR /F %%i in ('dir BACKUPDIR /b ^| find /v /c "::"') DO SET countfiles=%%i
if countfiles GTR 21 (
FOR /F %%i IN ('DIR /B /O-D %BACKUPDIR%') DO SET OLDEST=%%i
DEL %BACKUPDIR%\%OLDEST%
)
That's not working...you can't set 'normal' variables within a for-loop. I had the same problem some days ago and solved it with this blog entry.
Basically, you need to set SETLOCAL ENABLEDELAYEDEXPANSION and then use ! instead of %...
set FILES=
for /f %%a IN (‘dir /b *.txt’) do set FILES=!FILES! %%a
echo %FILES%
So, this should work for you:
SETLOCAL ENABLEDELAYEDEXPANSION
SET OLDEST=
FOR /F %%i IN ('DIR /B /O-D %BACKUPDIR%') DO SET OLDEST=%%i
DEL %BACKUPDIR%\%OLDEST%

Resources