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?
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:
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...
for %f in (.\\*) do @echo %f
for /D %s in (.\\*) do @echo %s
for /R %f in (.\\*) do @echo %f
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
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
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.
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.
If you use this on the commandline, remove a \"%\".
Hope this helps.
In bash, you might do something like this:
for fn in *; do
if [ -d $fn ]; then
echo \"$fn is a directory\"
fi
if [ -f $fn ]; then
echo \"$fn is a file\"
fi
done
I just noticed that you asked about batch, which I misread as bash. This answer may therefore be not appropriate to your question.
%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
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
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\".
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\"
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\"
)