46

I need to write a script to work in Windows, that when executed will run a command in some of sub-directories, but unfortunately I have never done anything in batch, and I don't know where to start.

With the example structure of folders:

\root
   \one
   \two
   \three
   \four

I want the script to enter the specified folders (e.g. only 'one' and 'four') and then run some command inside every child directories of that folders.

If you could provide any help, maybe some basic tutorial or just names of the commands I will need, I would be very grateful.

Kacper
  • 726
  • 1
  • 6
  • 22
  • how do you differentiate "one and four" from "two and three" ? Is there an algorithm which can tell us which to use ? – Marged Oct 22 '15 at 08:51
  • it shoul be hard coded, I need this to run always in the same directories – Kacper Oct 22 '15 at 08:58

5 Answers5

83

You can tell the batch to iterate directories:

for /d %i in (C:\temp\*) do ( cd "%i" &  *enter your command here* ) 

Use a percent sign when run directly on the command line, two when run from a batch

In a batch this would look something like this:

@echo off
set back=%cd%
for /d %%i in (C:\temp\*) do (
cd "%%i"
echo current directory:
cd
pause
)
cd %back%

Put the commands you need in the lines between ( and ). If you replace C:\temp\ with %1 you can tell the batch to take the value of the directory from the first parameter when you call it. Depending of the amount of directories you then either call the batch for each directory or read them from a list:

for /f %i in (paths.lst) do call yourbatch %i

The paths.lstwill look like this:

C:\
D:\
Y:\
C:\foo

All of this is written from memory, so you might need to add some quotations marks ;-) Please note that this will only process the first level of directories, that means no child folders of a selected child folder.

Ɖiamond ǤeezeƦ
  • 3,223
  • 3
  • 28
  • 40
Marged
  • 10,577
  • 10
  • 57
  • 99
  • if I copy code your code to a .file, and run it in CMD it says: "i was unexpected at this time". And if I wanted the script to run in current directory I simply replace C:\temp\ with a dot? – Kacper Oct 22 '15 at 09:14
  • Yes, it works. I did something wrong the previous time. I think I know what I should do now, thanks for help! – Kacper Oct 22 '15 at 09:32
  • Can you please look at this case? https://stackoverflow.com/questions/45482766/script-to-execute-command-to-all-files-in-folder?noredirect=1#comment77926070_45482766 – amelie Aug 03 '17 at 12:02
  • I wanted to do this from a list defined in the file itself, and I found this https://stackoverflow.com/a/16571278/3066295 – TT-- Nov 05 '18 at 22:17
  • 1
    command 'set back=%cd%' to save directory name can be replaced by pushd . and command 'cd %back%' to restore previous saved current folder can be replaced by 'popd'. – schlebe Feb 01 '19 at 06:26
9

You should take a look at this. The command you are looking for is FOR /R. Looks something like this:

FOR /R "C:\SomePath\" %%F IN (.) DO (
    some command
)
MichaelS
  • 5,941
  • 6
  • 31
  • 46
  • It would run in every subfolder, and I needed to run a command only in first child directiories. – Kacper Oct 22 '15 at 09:33
7

I like answer of Marged that has been defined as BEST answer (I vote up), but this answer has a big inconvenience.

When DOS command between ( and ) contains some errors, the error message returned by DOS is not very explicit.

For information, this message is

) was unexpected at this time.

To avoid this situation, I propose the following solution :

@echo off

pushd .
for /d %%i in (.\WorkingTime\*.txt) do call :$DoSomething "%%i"
popd

pause
exit /B

::**************************************************
:$DoSomething
::**************************************************

echo current directory: %1
cd %1
echo current directory: %cd%
cd ..

exit /B

The FOR loop call $DoSomething "method" for each directory found passing DIR-NAME has a parameter. Caution: doublequote are passed to %1 parameter in $DoSomething method.

The exit /B command is used to indicate END of method and not END of script.

The result on my PC where I have 2 folders in c:\Temp folder is

D:\@Atos\Prestations>call test.bat
current directory: ".\New folder"
current directory: D:\@Atos\Prestations\New folder
current directory: ".\WorkingTime"
current directory: D:\@Atos\Prestations\WorkingTime
Press any key to continue . . .

Caution: in Margeds answer, usage of cd "%%i" is incorrect when folder is relative (folder with . or ..).

Why, because the script goto first folder and when it is in first folder it request to goto second folder FROM first folder !

Stephan
  • 53,940
  • 10
  • 58
  • 91
schlebe
  • 3,387
  • 5
  • 37
  • 50
2

On Windows 10 and later, it should be like this:

@echo off
for /D %%G in ("C:\MyFolderToLookIn\*") DO ( 

echo %%~nxG

)

This will show the name of each folder in "C:\MyFolderToLookIn". Double quotes are required. If you want to show full path of the folder, change echo %%~nxG with echo %%G

CoolWolf
  • 19
  • 5
0

In BASH, that is Unix shell that can be also downloaded for Windows, I would definitely use find to do so along the lines

find . -mindepth 2 -maxdepth 2  -iregex ".*git.*\|.*out.*" -type d --exec echo {} \;

Feel free to modify it according to your needs.

VojtaK
  • 483
  • 4
  • 13