Batch process all files in directory - windows

Right now i have a batch job I wrote that calls another file and passes in the variables that executable needs to run (password and filename).
Ex:
> cd f:\test\utils
> admin import-xml -Dimport.file=f:\DB\file1.xml -Dadmin.db.password=test123
I wrote a job that does this, but found out that there would be multiple files.
The username and password never change but the filename differs for like 15 different xml files--with maybe more coming soon.
The files will always be located in the same folder. Instead of ending up with like 15-20 jobs (one for each file), can I write something that will process each file located in this directory. And either wait till one is completed before the next or I can add a 3 min sleep before it starts the next file.

pushd C:\test\utils
for %%F in (F:\DB\*.xml) do (
admin import-xml "-Dimport.file=%%~dpnxF" -Dadmin.db.password=test123
)
popd
The %%~dpnxF expands to d‎rive, p‎ath, base‎n‎ame and e‎x‎tension of the current file.
If you intend to set and use environment variables (%foo%) in that loop, read help set first before you get into trouble.

You can use the for command. Something like this in a batch file:
for %%f in (*.xml) do call myotherbatch.bat %%f
Assuming that the admin command you are running doesn't return until the job is finished, the above loop would process them sequentially.
If you run the command at the prompt (as opposed to in a batch file), only use a single %.

for file in f:\DB\*
do
admin import-xml -Dimport.file="$file" -Dadmin.db.password=test123
done

Related

Redirecting output of multiple bat files to one console window

I am running multiple microservices locally for development purposes. Currently I am doing it by a .bat script, where I am calling other .bat files, which are starting my services. It starts multiple console windows, and this is not handy to navigate between outputs.
The script which is starting services now looks like this:
start cmd /k call api_one.bat
start cmd /k call api_two.bat
...
In api_xxx.bat I am starting iisexpress with my api.
I am looking for a way to make it more comfortable. For example by redirecting all of the outputs to a single one, with for example a prefix to identify from which script output lines are from.
I had a similar problem, where I was calling a batch file from a batch file which started another batch file.. to complicated to explain but let me get you some code that helped me:
content from test.bat:
set logname=.\log.log
if exist %logname% ( type nul > %logname%
)
echo Now starting example.bat>>%logname%
call C:\example.bat >>%logname%
echo finished example.bat>>%logname%
so now here is content of example.bat:
echo starting integrated commands
start /b cmd /k "C:\example2.bat"
[some code to check for a process that starts in example2.bat]
echo finished integrated commands
and the content of example2.bat can be whatever you want and is also displayed in the logfile.
Note that my example2.bat has an exit at the end, because example.bat checks if example2.bat is running. only when it finishes it goes on with the script. For myself it worked out I got everything from all 3 scripts into one logfile.

bat/cmd file does not return back

I want to launch some .cmd file and to remain in the same directory.
C:\Oracle\Middleware\Oracle_Home\user_projects\domains\wl_server\bin\setDomainEnv.cmd
The problem is that while executing the setDomainEnv.cmd wit about 10 other cmd files called from it, I am left in totally another directory. And I want to be where I have started. As I always start in the same directory, I am adding a cd line:
Echo on
C:\Oracle\Middleware\Oracle_Home\user_projects\domains\wl_server\bin\setDomainEnv.cmd
Echo on
cd /d C:\workspaces\DS8\swprods\dist-4.1.8-local-devel\
No effect! Again I am left in
C:\Oracle\Middleware\Oracle_Home\user_projects\domains\wl_server>
And I never even see the 3,4 lines to appear in the console. I could understand all that if some of the inner skripts ended with error, but they finish OK, without errors.
It would be understandable if some of the scripts changed the dir to another disk and back change would need /d key. But all is done on the same C: disk.
All operations in the script are conducted in the same source directory. The directory is changed after leaving the batch file.
....................................................
C:\workspaces\DS8\swprods\dist-4.1.8-local-devel>if "Oracle" == "Apple" (set MEM
_ARGS=-Xms2048m -Xmx2048m -XX:CompileThreshold=8000 -XX:PermSize=128m -XX:MaxPermSize=256m -XX:MaxPermSize=256m )
C:\workspaces\DS8\swprods\dist-4.1.8-local-devel>if exist C:\Oracle\MIDDLE~1\ORACLE~1\USER_P~1\domains\WL_SER~1\bin\setStartupEnv.cmd (call "C:\Oracle\MIDDLE~1\ORACLE~1\USER_P~1\domains\WL_SER~1\bin\setStartupEnv.cmd" )
^this is the last run line of the script
"Why?" and sometimes I thought, "Wherefore?" and sometimes I thought, "Inasmuch as which? And how can I change the directory back?
Use call:
call C:\Oracle\Middleware\Oracle_Home\user_projects\domains\wl_server\bin\setDomainEnv.cmd
Call will invoke another script and after it gets completed - it will returns to your script.
If you do not use call - your execution flow goes to that another script but does not return back.
Use pushd to save the current directory then use popd to restore it after you run the other cmd file.
pushd .
call C:\Oracle\Middleware\Oracle_Home\user_projects\domains\wl_server\bin\setDomainEnv.cmd
popd
Good thing about pushd/popd is they work even if the other batch file changes the working directory to a directory on another drive.

Task Scheduled not running batch file

I have file which does somethings and it works fine if I run the file manually but it doesn't run when set up in task scheduler.
Batch file is in a folder on desktop on windows 7.
Any feedback will be helpful.
I've even tried this link solution didn't work.
Most likely in this case you need to make sure that the directory the script runs in ("Start in") is set correctly. Usually this is the same directory that contains your script. You can set this in the Scheduled Task's properties.
As a test, try moving the .bat file to a directory with basic permissions (maybe a shared directory for example).
I had the same problem as you. My .bat file was located in a folder with some restrictive permissions on it, so that only my user account could access it. Even though I had set up the task scheduler to use my credentials it still failed. Moving the .bat file to another directory sorted the issue.
I don't know if this will help, but in bashing my head against one problem after another for far too many hours, I finally got my own batch file to work properly as a scheduled task. Some of the things I learned in the process:
If you are the user who has created the scheduled task, you must also be a user who has logged into the system using a password.
Any reference to a file name, inside the batch file, needs to be the last part of fully qualified path, starting with drive letter.
If you do a comparison, like [%flag%] EQU [0], be aware that the "[" and "]" symbols are string literals that are included in the data that gets compared.
If part of your batch file sets a variable and includes a "FOR" loop that calls a subroutine in which you expect to change the variable, you need to make sure that the variable is originally initialized as early as possible in the batch file. That is, something like this:
IF ... (
SET %flag=0
FOR ... (CALL :subr)
IF [%flag%] EQU [1] ( main scheduled-task command goes here)
)
GOTO :eof
:subr
IF ... (SET %flag=1)
:eof
--worked from the command line, but not as a Scheduled Task. I had to move the initialization of %flag to be done before that very-first IF.

How to do a for loop in windows command line?

I was wondering if this was possible? I'm not familiar with using windows command line, but I have to use it for a project I'm working on. I have a a number of files, for which I need to perform a function for each. I'm used to working with python, but obviously this is a bit different, so I was hoping for some help.
Basically I need the for loop to iterate through 17 files in a folder, perform a function on each (that's using the specific software I have here for the project) and then that will output a file with a unique name (the function normally requires me to state the output file name) I would suck it up and just do it by hand for each of the 17, but basically it's creating a database of a file, and then comparing it to each of the 17. It needs to be iterated through several hundred times though. Using a for loop could save me days of work.
Suggestions?
The commandline interpreter does indeed have a FOR construct that you can use from the command prompt or from within a batch file.
For your purpose, you probably want something like:
FOR %i IN (*.ext) DO my-function %i
Which will result in the name of each file with extension *.ext in the current directory being passed to my-function (which could, for example, be another .bat file).
The (*.ext) part is the "filespec", and is pretty flexible with how you specify sets of files. For example, you could do:
FOR %i IN (C:\Some\Other\Dir\*.ext) DO my-function %i
To perform an operation in a different directory.
There are scores of options for the filespec and FOR in general. See
HELP FOR
from the command prompt for more information.
This may help you find what you're looking for...
Batch script loop
My answer is as follows:
#echo off
:start
set /a var+=1
if %var% EQU 100 goto end
:: Code you want to run goes here
goto start
:end
echo var has reached %var%.
pause
exit
The first set of commands under the start label loops until a variable, %var% reaches 100. Once this happens it will notify you and allow you to exit. This code can be adapted to your needs by changing the 100 to 17 and putting your code or using a call command followed by the batch file's path (Shift+Right Click on file and select "Copy as Path") where the comment is placed.
You might also consider adding ".
For example for %i in (*.wav) do opusenc "%~ni.wav" "%~ni.opus" is very good idea.

How do I run a BAT script without changing directories?

How do I run a BAT script without changing directories?
I am in ./a and the script cd's into ./a/bc. If I need to terminate my script for whatever reason I am now in bc instead of a. How do I run the script and not have my folder change?
Also, I don't like how it asks me if I'd like to terminate my script. Can I disable that and let it terminate?
The setlocal command is useful for this. Any directory changes after setlocal are just local to the batch script. BTW this also applies to any environment variables (set commands).
For example, after running this batch script:
cd /d c:\temp
setlocal
cd /d c:\windows
the directory will be c:\temp since the second cd in the script is just local to the script.
If you don't need to propagate environment variable changes into the current environment and cannot touch the batch file (to use the pushd/popd variant which I usually use), you can still spawn a new instance of cmd:
cmd /c myBatch.cmd arg1 arg2 ...
Also has the nice property of leaving your original batch file running even if the called batch throws up errors. I do that in my batch unit testing framework, for example, to ensure that a failing batch file won't stop the tests from executing.
You can run your script with start yourscript.bat. This makes it run in a new command window, and therefore does not affect the working directory of the command prompt that started the script.
Another possibility is to not use cd and use absolute paths instead.
The first question is: why do you need to change the directory? Can you simply work with paths relative to the one of your batch file? (e.g. using %~dp0\a\bc to reference the directory)
But if you really, really need to do that, you can do the following:
REM change the current directory
pushd ..\a\bc
.. do your stuff here
REM restore the old "current directory"
popd

Resources