My faithful path traversal method no longer works - it sees spaces as delimiters. It's been a while since I needed to do batch programming.
When using the FOR loop, the only one that allows delimiters are the FOR /F option.
I don't want to create a temporary file containing the path, was hoping to do something like below:
C:\Users>for /f "delims=;" %i in %path% do echo %i
C:\Program was unexpected at this time.
C:\Users>for /f "delims=;" %i in (%path%) do echo %i
\Common was unexpected at this time.
C:\Users>for /f "delims=;" %i in 'foo;bar' do echo %i
'foo was unexpected at this time.
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%a in (^"!path:^;^=^
% Do NOT remove this line %
!^") do echo %%a
Output example:
C:\Program Files (x86)\AMD APP\bin\x86_64
C:\Program Files (x86)\AMD APP\bin\x86
C:\Windows\system32
C:\Windows
C:\Windows\System32\Wbem
C:\Windows\System32\WindowsPowerShell\v1.0\
C:\Program Files (x86)\Windows Live\Shared
C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static
C:\Program Files\Bandizip\7z
A perfect solution must be able to differentiate between ; delimiters and quoted ; literals.
Here is a very robust solution that always works using JREPL.BAT - a regular expression find/replace utility
for /f "eol=: delims=" %%F in (
'jrepl "([^;\q]+|\q.*?(\q|$))+" $0 /x /jmatch /s path'
) do echo(%%F
If all you want to do is list each folder, one line per folder, then simply remove the FOR /F loop
call jrepl "([^;\q]+|\q.*?(\q|$))+" $0 /x /jmatch /s path
If you want a pure batch solution that always works, then you can use:
#echo off
setlocal DisableDelayedExpansion
set "var=%var:"=""%"
set "var=%var:^=^^%"
set "var=%var:&=^&%"
set "var=%var:|=^|%"
set "var=%var:<=^<%"
set "var=%var:>=^>%"
set "var=%var:;=^;^;%"
set var=%var:""="%
set "var=%var:"=""Q%"
set "var=%var:;;="S"S%"
set "var=%var:^;^;=;%"
set "var=%var:""="%"
setlocal EnableDelayedExpansion
set "var=!var:"Q=!"
for %%a in ("!var:"S"S=";"!") do (
if "!!"=="" endlocal
if %%a neq "" echo %%~a
)
The above is a slightly improved version of jeb's original solution
Use a standard for loop rather than for /F "delims=;" with some smart sub-string replacement:
for %I in ("%PATH:;=";"%") do #echo %~I
Supposing PATH contains C:\Program Files\someapp1\app1.exe;C:\Program Files\someapp2\app2.exe;C:\Program Files\someapp3\app3.exe, you will receive the following output:
C:\Program Files\someapp1\app1.exe
C:\Program Files\someapp2\app2.exe
C:\Program Files\someapp3\app3.exe
This works only in case none of the paths are surrounded by " and none of them contains ;.
In a batch script the code must be changed to this:
for %%I in ("%PATH:;=";"%") do #echo %%~I
Follow these Instructions from Mongodb .
cd C:\
md "\data\db"
After this step, you could once check in "C:\Program Files\MongoDB\Server\<Version Number>\bin\mongod.cfg"
there you could see, a default option of DBPath
# Where and how to store data.
storage:
dbPath: %MONGO_DATA_PATH%
journal:
enabled: true
# engine:
# mmapv1:
# wiredTiger:
Now add the %MONGO_DATA_PATH% variable in Environment variables of your system as key, where value is the file path ( where you have created the data/db folder)
now you could start mongod process without passing an argument of dbPath.
Related
I have a folder with four to five text files in it.
My overall aim is the following: Create one big file which has the content of the separate files, but in the right order.
I can use the time-stamp of each file to start with the oldest file up to the youngest.
My process right now looks like this:
Order the files in this folder by date.
Create a temporary file and write the content from the separate files into this file.
Output the temporary file.
In code I do something like this:
set temp_concat=%temp_dir%\temp_concat.log
echo %temp_concat%
echo aiu_logs > %temp_concat%
for /f "delims=" %%? in ('dir /b /o:d %Folder%*') do (
for /f "delims=" %%K in (%Folder%%%?) do (
echo %%K >>%temp_concat%
)
)
The above code seems to work as my temp_concat is very large.
However, this takes much much longer than expected. I have to wait about 40 seconds just to merge three files in my case.
Is there some better way of merging some amount of files, but keep them in the correct order by date?
This batch file uses the suggestion posted by Sqashman to use a FOR loop to create the arguments string for command COPY used to concatenate the file contents into a single file in the order of oldest modified file first and newest modified file last.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "Folder=%~dp0"
if not "%~1" == "" set "Folder=%~1"
set "Folder=%Folder:/=\%"
if not "%Folder:~-1%" == "\" set "Folder=%Folder%\"
set "ResultsFile=%Folder%Results.log"
del "%ResultsFile%" 2>nul
set "Arguments="
for /F "eol=| delims=" %%I in ('dir /A-D-H /B /O:D "%Folder%*" 2^>nul') do if not "%%~fI" == "%~f0" set "Arguments=!Arguments! + "%%I""
if defined Arguments (
echo aiu_logs>"%ResultsFile%"
copy /B "%ResultsFile%"%Arguments% "%ResultsFile%" >nul
)
endlocal
The batch file as is does not work if either the folder path or one of the file names contains one or more exclamation marks ! because of an enabled delayed environment variable expansion.
Further the command line length is limited and so this batch file does not work on too many files must be concatenated depending on length of the file path of each file and the length of the file names.
A better solution would be using following batch file:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "Folder=%~dp0"
if not "%~1" == "" set "Folder=%~1"
set "Folder=%Folder:/=\%"
pushd "%Folder%" 2>nul
if errorlevel 1 goto EndBatch
set "ResultsFile=Results.log"
del "%ResultsFile%" 2>nul
set "Arguments="
for /F "eol=| delims=" %%I in ('dir /A-D-H /B /O:D * 2^>nul') do if not "%%~fI" == "%~f0" call set "Arguments=%%Arguments%% + "%%I""
if defined Arguments (
echo aiu_logs>"%ResultsFile%"
copy /B "%ResultsFile%"%Arguments% "%ResultsFile%" >nul
)
popd
:EndBatch
endlocal
A folder path with one or more exclamation marks is no problem anymore. Also the file names can contain ! because of delayed expansion is not used by this batch file which is a bit slower than the first batch file.
The folder with the files to concatenate is made the current directory by this batch file. For that reason more file names can be specified as arguments on COPY command line in comparison to first batch file because of the file names are specified without path. But the number of file contents which can be merged with this batch file is nevertheless limited by the maximum length of a Windows command line respectively the maximum length of an environment variable value.
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.
call /?
copy /?
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
popd /?
pushd /?
set /?
setlocal /?
Read also the Microsoft article about Using command redirection operators for an explanation of > and 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background with %ComSpec% /c and the DIR command line between the two ' appended as further arguments.
The second FOR /F does not contain a command. It contains a filename. I have not tested this, but perhaps:
set temp_concat=%temp_dir%\temp_concat.log
echo %temp_concat%
echo aiu_logs > "%temp_concat%"
for /f "delims=" %%? in ('dir /b /o:d "%Folder%"') do (
if not "%%~f?" == "%~f0" (
type %%? >>"%temp_concat%"
)
)
This will concatenate all files in the "%Folder%" directory. Paths should be quoted in case there are special characters in them.
I have files named as RabcdYYMMKKACCOUNT.TXT in the Subfolders of a folder where YYMM is year, month this will change. KK is another identifier, I want all the files to be renamed to MSFKKDNB.ABC, the KK is the identifier in the input file.
Below is the one i tried and the result of it:
FOR /R %%f IN (*account.txt) DO REN "%%f" *dnb.abc
R00531706AUAccount.txt is renamed to R00531706AUAccount.txtdnb.abc
but the output should be MSFAUDNB.abc
This could be done for example with:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
for /R %%I in (???????????account.txt) do (
set "FileName=%%~nI"
set "NewFileName=MSF!FileName:~9,2!DNB.abc"
if not exist "%%~dpI!NewFileName!" (
ren "%%~fI" "!NewFileName!" 2>nul
if not exist "%%~dpI!NewFileName!" echo Failed to rename file: "%%~fI"
) else (
echo Cannot rename file: "%%~fI"
)
)
endlocal
The file name of found account text file is assigned to environment variable FileName.
The new name for the file is created by concatenating the fixed parts MSF and DNB.abc with the 2 characters to keep from file name using string substitution and delayed expansion.
Next it is checked if a file with new name does not already exist. Is this the case the file renaming is done otherwise an error message is output.
After renaming the file it is checked if that was successful. A slightly different error is output if renaming failed for example because of a sharing violation.
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 /?
endlocal /?
for /?
if /?
ren /?
set /?
setlocal /?
Read also the Microsoft article about Using Command Redirection Operators.
Try this:
#Echo Off
For %%A In ("*account.txt") Do (Set "_=%%~nA"
SetLocal EnableDelayedExpansion
Ren "%%A" "MSF!_:~-9,2!DNB.abc"
EndLocal)
I would probably do it the following way, provided that the files to rename are located in immediate sub-directories (YYMM) of the given root directory and nowhere else:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "_ROOT=." & rem // (specify path to the root directory)
for /D %%D in ("%_ROOT%\????") do (
for %%F in ("%_ROOT%\%%~nxD\R??????????Account.txt") do (
set "FDIR=%%~nxD" & set "FILE=%%~nxF"
setlocal EnableDelayedExpansion
ECHO ren "!_ROOT!\!FDIR!\!FILE!" "MSF!FILE:~9,2!DNB.abc"
endlocal
)
)
endlocal
exit /B
If you want to check whether both the sub-directory name and the year/month portion of the file names are purely numeric, you could use the following script:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "_ROOT=." & rem // (specify path to the root directory)
for /F "delims= eol=|" %%D in ('
dir /B /A:D "%_ROOT%\????" ^| ^
findstr "^[0123456789][0123456789][0123456789][0123456789]$"
') do (
for /F "delims= eol=|" %%F in ('
dir /B /A:-D "%_ROOT%\%%~nxD\R??????????Account.txt" ^| ^
findstr "^R....[0123456789][0123456789][0123456789][0123456789].."
') do (
set "FDIR=%%~nxD" & set "FILE=%%~nxF"
setlocal EnableDelayedExpansion
ECHO ren "!_ROOT!\!FDIR!\!FILE!" "MSF!FILE:~9,2!DNB.abc"
endlocal
)
)
endlocal
exit /B
If you want to check whether the sub-directory name matches the year/month (YYMM) portion of the file names, replace the pattern R??????????Account.txt by R????%%~nxD??Account.txt (for both scripts).
After having verified the correct output of either script, remove the upper-case ECHO commands to actually rename any files!
Basically, both scripts use sub-string expansion to extract the identifier part (KK) from the file names. Since there are variables set and read in the same block of code, delayed expansion is required for that. The second approach does not list the sub-directories and files by standard for loops, it uses the dir command, findstr to filter their names and a for /F loop to capture the resulting output for both sub-directories and files.
I am trying to copy some pictures from one folder and move it to another folder using batch. I am having trouble in setting the path since the path contains spaces in it.If I remove the spaces from folder it works fine but with spaces it gives error that cannot find the path.. here is the code.
#echo off
SET odrive=%odrive:~0,2%
setlocal enabledelayedexpansion
set backupcmd=echo
set backupcmd=xcopy /s /c /d /e /h /i /r /y
set "filesw=C:\Users\%USERNAME%\Numerical Analysis\*.png"
for /f "delims=" %%i in ('dir /s /b %filesw%') do (
if "%%~xi"==".pdf" set "dest=D"
if "%%~xi"==".docx" set "dest=P"
if "%%~xi"==".zip" set "dest=Z"
if "%%~xi"==".rar" set "dest=Z"
if "%%~di"=="C:" if "!dest!"=="Z" set "dest=!dest!3"
%backupcmd% "%%i" "%drive%\Personal\PICS\Wedding\Barat\MOVIE!dest!\"
)
#echo off
cls
It would be really helpful if you guys help me fix this path problem.
The solution to your problem, specifically "setting the path since the path contains spaces in it" leading to "cannot find the path" is to "quote the filespec" Thus:
for /f "delims=" %%i in ('dir /s /b "%filesw%"') do (
In this way, the string between the double-quotes is used literally (although certain special characters with a meaning to batch like &^)! need to be escaped; that is, preceded by a caret ^). As you have it, the dir command will be executed with multiple arguments since spaces are separators and the variable filesw will be substituted literally into the dir command before execution - and like most commands, dir uses spaces (commas, tabs, semicolons) as separators.
This is how I would do it. Use the FOR /R command to walk the directory tree looking for the file type you want. But I am just guessing at what you are trying to do.
#echo off
setlocal enabledelayedexpansion
set backupcmd=xcopy /s /c /d /e /h /i /r /y
set "filep=C:\Users\%USERNAME%\Numerical Analysis"
for /R "%filep%" %%i in (.) do (
if "%%~xi"==".pdf" set "dest=D"
if "%%~xi"==".docx" set "dest=P"
if "%%~xi"==".zip" set "dest=Z"
if "%%~xi"==".rar" set "dest=Z"
if "%%~di"=="C:" if "!dest!"=="Z" set "dest=!dest!3"
%backupcmd% "%%i" "%drive%\Personal\PICS\Wedding\Barat\MOVIE!dest!\"
)
I am trying to convert a long filename to a short filename (8.3) on Windows.
A batch-file with a command line argument works as intended:
short.bat:
#echo OFF
echo %~s1
calling short.bat C:\Documents and Settings\User\NTUSER.DAT returns C:\DOCUM~1\USER\NTUSER.DAT
However, I don't like having an extra .bat-file for this. I would rather call cmd.exe with the whole command from a ruby script.
How can I do this?
As an intermediate step I tried to hardcode the path in the batch-file, but that does not work:
short1.bat:
#echo OFF
SET filename="C:\Documents and Settings\User\NTUSER.DAT"
echo %filename%
echo %~sfilename%
echo %filename% works, but echo %~sfilename% gives the following error:
The following usage of the path operator in batch-parameter
substitution is invalid: %~sfilename%
For valid formats type CALL /? or FOR /?
If short1.bat works, how can I convert this into a one-liner that can be called with cmd.exe \c ...?
There is another question (how to get DOS path instead of Windows path), however that one is specifically asking for the path of the current directory.
cmd /c for %A in ("C:\Documents and Settings\User\NTUSER.DAT") do #echo %~sA
Replace the filename.txt to the filename you want to convert to 8.3
dir /x filename.txt
You will then have to split the result with whitespace as your delimiter (\s in regex).
Then the value with the ~ is your short filename. If your filename is short to begin with, then you won't find a string containing a ~.
Here is an example that read in the registry the location of your "appdata\local" folder and convert it to short path:
cls
#echo off
cd /d "%~dp0"
chcp 65001 >nul
for /f "skip=1" %%a in ('"wmic useraccount where name='%USERNAME%' get sid"') do (
for %%b in (%%a) do set current_SID=%%b
)
set current_username=%USERNAME%
set current_userprofile=%USERPROFILE%
set key_to_read=HKEY_USERS\%current_SID%\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
set value_to_read=Local AppData
rem If value_to_read contains ? space(s) set tokens to 2+?
for /f "usebackq eol= tokens=3,* delims= " %%a in (`reg query "%key_to_read%" /v "%value_to_read%" 2^>nul ^| find "%value_to_read%"`) do (
set value_type=%%a
set data_read=%%b
)
set data_read=%data_read:USERPROFILE=current_userprofile%
call set "data_read=%data_read%"
set current_local_appdata=%data_read%
set current_local_appdata_temp=%current_local_appdata%\Temp
echo %current_local_appdata_temp%
for %%a in ("%current_local_appdata_temp%") do set "current_local_appdata_temp_short=%%~sa"
echo %current_local_appdata_temp_short%
pause
exit
How can I iterate over each file in a directory using a for loop?
And how could I tell if a certain entry is a directory or if it's just a file?
This lists all the files (and only the files) in the current directory and its subdirectories recursively:
for /r %i in (*) do echo %i
Also if you run that command in a batch file you need to double the % signs.
for /r %%i in (*) do echo %%i
(thanks #agnul)
Iterate through...
...files in current dir: for %f in (.\*) do #echo %f
...subdirs in current dir: for /D %s in (.\*) do #echo %s
...files in current and all subdirs: for /R %f in (.\*) do #echo %f
...subdirs in current and all subdirs: for /R /D %s in (.\*) do #echo %s
Unfortunately I did not find any way to iterate over files and subdirs at the same time.
Just use cygwin with its bash for much more functionality.
Apart from this: Did you notice, that the buildin help of MS Windows is a great resource for descriptions of cmd's command line syntax?
Also have a look here: http://technet.microsoft.com/en-us/library/bb490890.aspx
To iterate over each file a for loop will work:
for %%f in (directory\path\*) do ( something_here )
In my case I also wanted the file content, name, etc.
This lead to a few issues and I thought my use case might help. Here is a loop that reads info from each '.txt' file in a directory and allows you do do something with it (setx for instance).
#ECHO OFF
setlocal enabledelayedexpansion
for %%f in (directory\path\*.txt) do (
set /p val=<%%f
echo "fullname: %%f"
echo "name: %%~nf"
echo "contents: !val!"
)
*Limitation: val<=%%f will only get the first line of the file.
There is a subtle difference between running FOR from the command line and from a batch file. In a batch file, you need to put two % characters in front of each variable reference.
From a command line:
FOR %i IN (*) DO ECHO %i
From a batch file:
FOR %%i IN (*) DO ECHO %%i
This for-loop will list all files in a directory.
pushd somedir
for /f "delims=" %%f in ('dir /b /a-d-h-s') do echo %%f
popd
"delims=" is useful to show long filenames with spaces in it....
'/b" show only names, not size dates etc..
Some things to know about dir's /a argument.
Any use of "/a" would list everything, including hidden and system attributes.
"/ad" would only show subdirectories, including hidden and system ones.
"/a-d" argument eliminates content with 'D'irectory attribute.
"/a-d-h-s" will show everything, but entries with 'D'irectory, 'H'idden 'S'ystem attribute.
If you use this on the commandline, remove a "%".
Hope this helps.
%1 refers to the first argument passed in and can't be used in an iterator.
Try this:
#echo off
for %%i in (*.*) do echo %%i
I had trouble getting jop's answer to work with an absolute path until I found this reference: https://ss64.com/nt/for_r.html
The following example loops through all files in a directory given by the absolute path.
For /R C:\absoulte\path\ %%G IN (*.*) do (
Echo %%G
)
Here's my go with comments in the code.
I'm just brushing up by biatch skills so forgive any blatant errors.
I tried to write an all in one solution as best I can with a little modification where the user requires it.
Some important notes: Just change the variable recursive to FALSE if you only want the root directories files and folders processed. Otherwise, it goes through all folders and files.
C&C most welcome...
#echo off
title %~nx0
chcp 65001 >NUL
set "dir=c:\users\%username%\desktop"
::
:: Recursive Loop routine - First Written by Ste on - 2020.01.24 - Rev 1
::
setlocal EnableDelayedExpansion
rem THIS IS A RECURSIVE SOLUTION [ALBEIT IF YOU CHANGE THE RECURSIVE TO FALSE, NO]
rem By removing the /s switch from the first loop if you want to loop through
rem the base folder only.
set recursive=TRUE
if %recursive% equ TRUE ( set recursive=/s ) else ( set recursive= )
endlocal & set recursive=%recursive%
cd /d %dir%
echo Directory %cd%
for %%F in ("*") do (echo → %%F) %= Loop through the current directory. =%
for /f "delims==" %%D in ('dir "%dir%" /ad /b %recursive%') do ( %= Loop through the sub-directories only if the recursive variable is TRUE. =%
echo Directory %%D
echo %recursive% | find "/s" >NUL 2>NUL && (
pushd %%D
cd /d %%D
for /f "delims==" %%F in ('dir "*" /b') do ( %= Then loop through each pushd' folder and work on the files and folders =%
echo %%~aF | find /v "d" >NUL 2>NUL && ( %= This will weed out the directories by checking their attributes for the lack of 'd' with the /v switch therefore you can now work on the files only. =%
rem You can do stuff to your files here.
rem Below are some examples of the info you can get by expanding the %%F variable.
rem Uncomment one at a time to see the results.
echo → %%~F &rem expands %%F removing any surrounding quotes (")
rem echo → %%~dF &rem expands %%F to a drive letter only
rem echo → %%~fF &rem expands %%F to a fully qualified path name
rem echo → %%~pF &rem expands %%A to a path only
rem echo → %%~nF &rem expands %%F to a file name only
rem echo → %%~xF &rem expands %%F to a file extension only
rem echo → %%~sF &rem expanded path contains short names only
rem echo → %%~aF &rem expands %%F to file attributes of file
rem echo → %%~tF &rem expands %%F to date/time of file
rem echo → %%~zF &rem expands %%F to size of file
rem echo → %%~dpF &rem expands %%F to a drive letter and path only
rem echo → %%~nxF &rem expands %%F to a file name and extension only
rem echo → %%~fsF &rem expands %%F to a full path name with short names only
rem echo → %%~dp$dir:F &rem searches the directories listed in the 'dir' environment variable and expands %%F to the fully qualified name of the first one found. If the environment variable name is not defined or the file is not found by the search, then this modifier expands to the empty string
rem echo → %%~ftzaF &rem expands %%F to a DIR like output line
)
)
popd
)
)
echo/ & pause & cls
To iterate through all files and folders you can use
for /F "delims=" %%a in ('dir /b /s') do echo %%a
To iterate through all folders only not with files, then you can use
for /F "delims=" %%a in ('dir /a:d /b /s') do echo %%a
Where /s will give all results throughout the directory tree in unlimited depth. You can skip /s if you want to iterate through the content of that folder not their sub folder
Implementing search in iteration
To iterate through a particular named files and folders you can search for the name and iterate using for loop
for /F "delims=" %%a in ('dir "file or folder name" /b /s') do echo %%a
To iterate through a particular named folders/directories and not files, then use /AD in the same command
for /F "delims=" %%a in ('dir "folder name" /b /AD /s') do echo %%a
for %1 in (*.*) do echo %1
Try "HELP FOR" in cmd for a full guide
This is the guide for XP commands. http://www.ss64.com/nt/
The following code creates a file Named "AllFilesInCurrentDirectorylist.txt" in the current Directory, which contains the list of all files (Only Files) in the current Directory. Check it out
dir /b /a-d > AllFilesInCurrentDirectorylist.txt
It could also use the forfiles command:
forfiles /s
and also check if it is a directory
forfiles /p c:\ /s /m *.* /c "cmd /c if #isdir==true echo #file is a directory"
I would use vbscript (Windows Scripting Host), because in batch I'm sure you cannot tell that a name is a file or a directory.
In vbs, it can be something like this:
Dim fileSystemObject
Set fileSystemObject = CreateObject("Scripting.FileSystemObject")
Dim mainFolder
Set mainFolder = fileSystemObject.GetFolder(myFolder)
Dim files
Set files = mainFolder.Files
For Each file in files
...
Next
Dim subFolders
Set subFolders = mainFolder.SubFolders
For Each folder in subFolders
...
Next
Check FileSystemObject on MSDN.
I use the xcopy command with the /L option to get the file names. So if you want to get either a directory or all the files in the subdirectory you could do something like this:
for /f "delims=" %%a IN ('xcopy "D:\*.pdf" c:\ /l') do echo %%a
I just use the c:\ as the destination because it always exists on windows systems and it is not copying so it does not matter. if you want the subdirectories too just use /s option on the end. You can also use the other switches of xcopy if you need them for other reasons.
Try this to test if a file is a directory:
FOR /F "delims=" %I IN ('DIR /B /AD "filename" 2^>^&1 ^>NUL') DO IF "%I" == "File Not Found" ECHO Not a directory
This only will tell you whether a file is NOT a directory, which will also be true if the file doesn't exist, so be sure to check for that first if you need to. The carets (^) are used to escape the redirect symbols and the file listing output is redirected to NUL to prevent it from being displayed, while the DIR listing's error output is redirected to the output so you can test against DIR's message "File Not Found".
try this:
::Example directory
set SetupDir=C:\Users
::Loop in the folder with "/r" to search in recursive folders, %%f being a loop ::variable
for /r "%SetupDir%" %%f in (*.msi *.exe) do set /a counter+=1
echo there are %counter% files in your folder
it counts .msi and .exe files in your directory (and in the sub directory). So it also makes the difference between folders and files as executables.
Just add an extension (.pptx .docx ..) if you need to filter other files in the loop
In my case I had to delete all the files and folders underneath a temp folder. So this is how I ended up doing it. I had to run two loops one for file and one for folders. If files or folders have spaces in their names then you have to use " "
cd %USERPROFILE%\AppData\Local\Temp\
rem files only
for /r %%a in (*) do (
echo deleting file "%%a" ...
if exist "%%a" del /s /q "%%a"
)
rem folders only
for /D %%a in (*) do (
echo deleting folder "%%a" ...
if exist "%%a" rmdir /s /q "%%a"
)