I would like to read two parameters that are passed to a batch file. The batch file will be executed from a C++ program using CreateProcess method. The second parameter to the batch file is a folder path, so from the program if I am passing the second parameter such as "E:\test folder\test2" the batch file does not get executed.
But if I instead pass E:\test folder\test2 the batch file gets executed but obviously the second parameter has the value E:\test only.. So what I would like to do is to read the first parameter using %1 and get the rest of the contents into another variable.
Can some one tell me how I can achieve this ? I tried with %* but it gives me both first and second parameters. I would like to remove the first token with space as delimiter so that I have the rest of the contents in the variable. Is there a way to do this ?
For example If I pass test.bat testparameter1 E:\test folder\test folder2\test folder3
I would like to read the value E:\test folder\test folder2\test folder3 into a variable.
If I pass test.bat testparameter1 E:\test\test folderX\test folderY the valueIi want to read in to a variable inside the batch file is E:\test\test folderX\test folderY
Can someone help me with this ? Thanks in advance.
Could you change spaces in the path by another character in your C++ code? For example, if we change spaces by arroba, then you could pass this:
test.bat testparameter1 E:\test#folder\test#folder2\test#folder3
and in the Batch file do the opposite change this way:
set param2=%2
set param2=%param2:#= %
Another possible method is to collect all the parameters from the second one on in the same variable, separating each one by one space:
set param1=%1
shift
set param2=
:nextParam
set param2=%param2% %1
shift
if not "%1" == "" goto nextParam
If your batch file is called with
test.bat testparam1 "E:\test\folder2\test folder 3"
You can read the parameters using %1 and %2
rem Contents of test.bat
#echo %0
#echo %1
#echo %2
The above produces:
C:\Temp>test testparam1 "E:\test\folder2\test folder 3"
test.bat
testparam1
"E:\test\folder2\test folder 3"
C:\Temp>
So you already have the parameters as variables; they're called %1 for the first one, %2 for the second, and so forth.
If the problem is that you're trying to do something using the "E:\test\folder2\test folder 3" path, just make sure you add a trailing backslash before passing it in:
"E:\test\folder2\test folder 3\"
Related
I want to run experiments using behavior space. However, the number of experiments needed is depending on the length of a list which is dynamic subject to the external data loaded. Hence , I want to do something like below which is not supported:
what is the correct way to do so? thanks
You note that you do this with a .bat or .sha file. If that's the case, here's a .bat solution. However, I'm not sure what your data looks like- in this example I just used the number of entries in a csv file to determine the number of runs needed.
So, I have a data file called 'example_data.csv' that looks like this:
1
100
1000
10000
I have an .nlogo file with an Input widget that defines a global variable called n_runs. I pulled out the xml for an BehaviorSpace experiment and saved it in a file called "experiment_base.xml"- it looks like:
<experiments>
<experiment name="experiment" repetitions="1" sequentialRunOrder="false" runMetricsEveryStep="false">
<setup>setup</setup>
<go>tick</go>
<timeLimit steps="5"/>
<metric>count turtles</metric>
<steppedValueSet variable="n_runs" first="1" step="1" last="1"/>
</experiment>
</experiments>
I have a .bat file that:
counts the number of entries in my 'example_data.csv"
reads in the 'experiment_base.xml' file and replaces the last="1" with the number read above, then writes this as a new experiment called 'mod_experiments.xml'
runs the experiment using the newly generated experiments file
This entire bat file looks like:
#echo off
cls
setlocal EnableDelayedExpansion
set "cmd=findstr /R /N "^^" example_data.csv | find /C ":""
for /f %%a in ('!cmd!') do set number=%%a
powershell -Command "(gc experiment_base.xml) -replace '<steppedValueSet variable=\"n_runs\" first=\"1\" step=\"1\" last=\"1\"/>', '<steppedValueSet variable=\"n_runs\" first=\"1\" step=\"1\" last=\"%number%\"/>' | Set-Content mod_experiments.xml
echo "Running experiment..."
netlogo-headless.bat ^
--model dynamic_behaviorspace.nlogo ^
--setup-file mod_experiments.xml ^
--table table-output.csv
This outputs results for 4 experiments, since I had 4 values in my data file. If I modify the number of entries in the csv and rerun the .bat file, I get results for a corresponding number of runs.
I have a batch file that runs off a powershell command I created, and I want to make it so you can pass a variable from the PS command to a website url query..
My problem is that the variables I pass from PS are referenced in batch as %1, %2, %n
now I set these variables at the beginning to more meaningful named variables, but in my url eg: www.google.com/myQuery%20has%20spaces would print out my %2 variable from PS instead of a space.
Is there anyway to clear out the %1,%2 variables that are passed? or any work around?
edit: I have tried a simple set %1= to try and set it as a null variable but it didn't work.
You can escape the % in the string with a %% in batch, which solves the issue.
I'm using tshell to connect to a device and I need to check if a given path is a file or directory.
I was hoping to use the cmd-device function which runs cmd commands on the device, but there doesn't seem to be a cmd command to do this.
Does someone have a way to check whether a given path is to a directory or to a file using the standard cmd functions?
Since you have PowerShell tagged in your question, one option would be to check the object type returned by the Get-Item cmdlet.
(Get-Item C:\Windows) -is [System.IO.DirectoryInfo]
# Shorter version
(gi C:\Windows) -is [IO.DirectoryInfo]
The usual test for a folder existence is
if exist "x:\somewhere\" echo FOLDER FOUND
but, in some cases (i know the case of novell netware redirector) the previous condition will always evaluate to true, both when "x:\somewhere" is a file or when it is a folder
One alternative can be
#echo off
setlocal enableextensions
set "target=c:\windows"
set "what=NOT EXIST"
for %%a in ("%target%") do for /f "delims=r-" %%b in ("%%~aa%%~za"
) do if "%%b"=="d" ( set "what=FOLDER" ) else ( set "what=FILE" )
echo %what%
endlocal
Check for the presence of an initial d in the list of attributes of the file/folder.
Each of the attributes in the list can be a letter (depending on the attribute) or a dash.
The two first are d for directory and r for readonly. So, second for uses r- as delimiters to separate the possible d from the rest of attributes.
If the file does not have any attributes set, the tokenizer in for command will eliminate all the dashes, non assigning data to the replaceable parameter and in consecuence not executing the code inside the do clause. To avoid it, %%~za (the size of the element) is appended to the string, so, there will always be data to be processed if the file/folder exists. If it does not exist, the expresion %%~aa%%~za is evaluated to a empty string and the code in the do clause will not execute.
Im trying to create a batch script to call a .exe to carry out analysis on multiple data files in a same folder. The syntax should be like:
"D:\Softwares\Analyzer.exe" [DataFile1].dat [DataFile2].dat ... [DataFileN].dat AnalysisFile.pdo"
Currently I have tried to use a FOR loop to scan each *.dat file in a specified folder. (I don't know how many data files in that folder, so I cannot type the filenames directly in the command line)
For example:
#ECHO OFF
FOR /r %%i in (*.dat) DO (
"D:\Softwares\Analyzer.exe" %%~ni.dat TestAnalysis.pdo
)
PAUSE
However, the analysis is carried out on seperate datafiles, and the .exe file will pop-up and open every time when a new .dat file is detected. Is there any way I could use *.dat or any other methods to represent [DataFile1].dat [DataFile2].dat ... [DataFileN].dat in one line seperated by a space (not a new line)?
I have also tried to use #tilte, which does not work as well. Since the .exe window keep pop-up whenever a new .dat file is detected and I have to close each of them in order to continue to next .dat file.
In general, I would like to do an automatic scan in a folder, get the names of the datafiles, and write a command line to call these .dat files in one line.
Any ideas/helps appreciated!!!
try this, remove the word echo if the output is OK:
#echo off &setlocal enabledelayedexpansion
set "line="
for %%i in (*.dat) do set "line=!line! "%%i""
echo "D:\Softwares\Analyzer.exe" %line% TestAnalysis.pdo
The code doesn't work with *dat files with exclams ! in the file name. This may be fixed if needed.
I have a collection of ZIP archives residing in a collection of folders inside Folder1\, with more than one zip file per folder.
I want to create a duplicate of this folder structure in another destination folder Destination\, but with all the ZIP files encrypted.
the folders inside Folder1\ are never nested any deeper than one, but a general solution that recurses into folders would be nice.
I have messed around with substrings but cannot get it to work. I'm sure I'm only a % away but it's got me stumped:
for /D %%S in (.\*) do (
echo %%S
set PN=%%S:~2,99%
echo %PN%
for %%F in (%%S\*.zip) do (
echo "%UserProfile%\Desktop\Destination\%PN%\%%~nxF"
)
)
the %%S returns a path in the form ".\Folder" and "set PN=%%S:~2,99%" is supposed to remove the ".\" but it ain't happening.
echo $$S displays ".\Folder" (without the quotes) which is OK
echo %PN% displays ".\Folder:~2,99" which is not OK
I'm OK with the unzipping/zipping, it's just the pathnames that have me stumped.
There are some issues with your script.
You cannot use substring expressions with a loop variable. You'll have to store its value to an environment variable (like SET name=%%S) and extract the substring from that variable.
Without enabling delayed expansion of variables you won't be able to use environment variables inside a command block enclosed in parentheses, if the vars are initialised within that same block. The problem is, the commands within the block are parsed (and vars are evaluated) at the same time the parent command is parsed (FOR in this case). So most probably you'll always have an empty string in place of %PN% there.
Actually you don't need the PN var. Seems like you've only introduced it to drop the .\ part of the folder name. But you don't have to use the .\* mask in the outer FOR loop, just use * instead. (Still, if .\* seems to you more meaningful, you can simply use %%~nxS where you need to substitute the folder's name.)
So, this should give you the expected output:
for /D %%S in (*) do (
for %%F in ("%%S\*.zip") do (
echo "%UserProfile%\Desktop\Destination\%%S\%%~nxF"
)
)
And if you insist on using the .\* mask:
for /D %%S in (.\*) do (
for %%F in ("%%~nxS\*.zip") do (
echo "%UserProfile%\Desktop\Destination\%%~nxS\%%~nxF"
)
)