This is my Windows script which is started every x minutes:
cd C:\
cd Speedtest
speedtest.exe -s 18571 -f csv>>Speedtest.log
How to add a timestamp to every log line?
Let us assume the application speedtest runs just one test run on each execution and outputs one or more lines without empty lines and on each line the current time on starting this application should be written first into the CSV file with , as list separator (default in most countries for CSV files). In this case the following batch file could be used for this task:
#cd /D "C:\Speedtest" 2>nul && #for /F delims^=^ eol^= %%I in ('speedtest.exe -s 18571 -f csv') do >>"Speedtest.log" #echo %TIME%,%%I
The first command CD changes the current directory to C:\Speedtest. This command fails if the directory does not exist. The error message output on changing directory failed is redirected with 2>nul from handle STDERR (standard error) to device NUL to suppress it. There is nothing output by CD if the current directory could be successfully changed to the specified directory.
The operator && results in executing the next command FOR only if CD exited with 0 indicating a successful change of the current directory which means the specified directory C:\Speedtest really exists.
FOR with option /F and a set specified between two ' results in execution of one more command process in background with %ComSpec% /c and the strings between the two ' appended as further arguments. So executed is on Windows installed to C:\Windows:
C:\Windows\System32\cmd.exe /c speedtest.exe -s 18571 -f csv
The started Windows command process executes speedtest.exe with the four specified arguments and then closes itself because of option /c.
FOR captures all output written to handle STDOUT (standard output) and processes it after started cmd.exe terminated itself.
FOR ignores all empty lines on processing the captured lines.
FOR would split up by default each line into substrings using normal space and horizontal tab as string delimiters and would assign just first space/tab separated string of a non-empty line to specified loop variable I. This string splitting behavior is not wanted here. For that reason option delims= is used to define an empty list of string delimiters which disables line splitting behavior.
FOR would ignore by default all lines on which first substring starts with a semicolon because of eol=; is the default for end of line option. It is unknown if speedtest outputs the lines with a semicolon at beginning. For that reason the option eol= is used to define no end of line character which means all lines except empty lines are assigned completely to specified loop variable I.
The two options delims= and eol= are specified usually in a double quoted argument string to get the two equal signs and the space character between interpreted as literal characters and not as argument separators by Windows command processor. But "delims= eol=" cannot be used here as FOR would interpret in this case " as end of line character. Therefore the two options must be written without " which requires escaping the two equal signs and the space character with ^ to be interpreted as literal character instead of argument separators by Windows command processor.
Windows command processor parses the entire line before execution of command CD and replaces during this parsing process %TIME% by the current value of the local time in format defined by the country configured for the account used to run this batch file. So the time written into the CSV file is the time on which the entire command line was parsed by cmd.exe before executing the command CD and on success next the other commands and executables.
The redirection operator >> with the file name Speedtest.log is specified left to command ECHO to be 100% safe that the line is written correct into the file without a trailing space even on ending with number 1 to 9. It can be seen on running this batch file from within a command prompt window without the three # that cmd.exe moved >>"Speedtest.log" to end of the command line with inserting left to this string a space and 1 before executing command CD. It must be always taken into account how a command line looks like after processing it by Windows command processor before executing the command and not how it is written in the batch file.
Note: If the configured country is Germany, Austria, Switzerland, Luxembourg or Liechtenstein with time format HH:mm:ss,ms and list separator ;, it is necessary to use a semicolon instead of a comma between %TIME% and %%I to produce a valid CSV file. speedtest outputs the data in this case hopefully also with ; instead of ,. Otherwise if speedtest outputs the data independent on list separator of the configured country always with a comma, it would be necessary to use on command ECHO either "%TIME%",%%I or %TIME:,=.%,%%I to get a valid CSV file using comma as separator.
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.
cd /?
echo /?
for /?
set /?
See also:
How does the Windows Command Interpreter (CMD.EXE) parse scripts?
Single line with multiple commands using Windows batch file
Microsoft article about Using command redirection operators
Related
I am trying to assign the output of the command python --version to a variable in batch script but it does not work.
Here is the sample code I am using
FOR /F "tokens=* USEBACKQ" %%F IN (`python --version`) DO (
SET message=%%F
)
ECHO %message%
Although it prints the version for python, it does not assign to the variable var.
If I use another command instead of python --version then the output is correctly assigned. e.g. using dir works.
What could be wrong?
NOTE -
#echo off
set message=Hello
FOR /F "tokens=* USEBACKQ" %%F IN (`python --version`) DO (
SET message=%%F
)
ECHO %message%
PAUSE
OUTPUT -
C:\Users\nik>extra.bat
Python 2.7.9
Hello
Press any key to continue . . .
The installed version of Python outputs obviously the version information to handle STDERR (standard error) instead of handle STDOUT (standard output). For that reason it is necessary to redirect the standard error stream with the version information to standard output stream using 2>&1 as described by Microsoft in the documentation about Using command redirection operators.
The command line to use is:
for /F "delims=" %%I in ('python.exe --version 2^>^&1') do set "message=%%I"
The redirection operators > and & must be escaped with caret character ^ on FOR command line to be interpreted as literal characters when Windows command interpreter processes this command line before executing command FOR.
FOR respectively cmd.exe processing the batch file with this command line starts in background one more command process with %ComSpec% /c and the command line specified within ' appended as additional arguments. Therefore is executed with Windows installed into C:\Windows in the background:
C:\Windows\System32\cmd.exe /c python.exe --version 2>&1
The command process in background searches now for an executable python.exe as described at What is the reason for "X is not recognized as an internal or external command, operable program or batch file"? When the file python.exe could be found by cmd.exe running in background without a visible console window, it executes it and Python outputs the version information to standard error stream which is redirected to standard output stream of the background command process.
The started cmd.exe closes itself after python.exe terminated itself after printing the version information.
The cmd.exe instance processing the batch file captures everything written to handle STDOUT of started background command process and FOR processes the captured lines after started cmd.exe closed itself.
There is split up by default a non-empty captured line into substrings using normal space and horizontal tab as string delimiters. If the first substring after removal of 0 or more leading spaces/tabs starts with a semicolon, the captured line is ignored, otherwise the first substring is assigned to the specified loop variable I.
The default line handling behavior is not wanted here. For that reason the for /F option delims= defines an empty list of string delimiters to disable the line splitting behavior to get the entire captured line assigned to the specified loop variable I. The implicit default eol=; (semicolon is end of line) can be kept in this case as the version information output by Python starts never with a semicolon.
I have the following batch file to make git diff invoke spreadsheet compare UI in windows. So I'm trying to pass the git diff's 2nd (old file) and 5th (new file) arguments to spreadsheet compare in order to make it compare the file using git diff.
So now, this batch file only successfully handles files with NO spaces in the file names, it CANNOT handle files with spaces in the file names.
What code should I add to this script to make this batch code handles file with spaces:
#ECHO OFF
set path2=%5
set path2=%path2:/=\%
ECHO %2 > tmp.txt
dir %path2% /B /S >> tmp.txt
C:/"Program Files"/"Microsoft Office"/root/vfs/ProgramFilesX86/"Microsoft Office"/Office16/DCF/SPREADSHEETCOMPARE.EXE tmp.txt
It currently throw errors like this:
Unhandled Exception: System.ArgumentException: Illegal characters in path.
at System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional)
at System.IO.Path.GetFileName(String path)
at ProdianceExcelCompare.Form1.StatusReady()
at ProdianceExcelCompare.Form1.Init()
at ProdianceExcelCompare.Form1..ctor(String instructionFile)
at ProdianceExcelCompare.Program.Main(String[] args)
fatal: external diff died, stopping at London comparison.xlsx
See the following answers on Stack Overflow:
How to set environment variables with spaces?
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
They explain the recommended syntax set "VariableName=variable value" to define an environment variable and the reasons recommending this syntax.
Why does ECHO command print some extra trailing space into the file?
It explains why the space character left to redirection operator > on an ECHO command line is also written into the file as trailing space and how to avoid this safely on variable text written into the file.
See also Microsoft documentation about Using command redirection operators.
On other command lines than ECHO a space left to > is usually no problem.
It is in general wrong to use multiple times " within an argument string like a file or folder path. There should be just one " at beginning and one " at end. This is explained by help of Windows command processor output on last help page on running in a command prompt window cmd /?.
The Microsoft documentation about Naming Files, Paths, and Namespaces explains that the directory separator on Windows is \ and not / and therefore / should not be used in batch files on Windows in file/folder paths.
The help output on running in a command prompt window call /? explains how the arguments of a batch file can be referenced with which modifiers.
The code rewritten according to information posted above and on the referenced pages:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "path2=%~5"
set "path2=%path2:/=\%"
>"tmp.txt" echo %2
dir "%path2%" /B /S >>"tmp.txt" 2>nul
"%ProgramFiles%\Microsoft Office\root\vfs\ProgramFilesX86\Microsoft Office\Office16\DCF\SPREADSHEETCOMPARE.EXE" "tmp.txt"
endlocal
The first line in tmp.txt contains the second argument as passed to the batch file, i.e. without or with surrounding double quotes.
The following code is necessary to write the second argument safely always without " into file tmp.txt even on second argument passed to the batch file is "Hello & welcome!":
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "path2=%~5"
set "path2=%path2:/=\%"
set "Argument2=%~2"
setlocal EnableDelayedExpansion
echo !Argument2!>"tmp.txt"
endlocal
dir "%path2%" /B /S >>"tmp.txt" 2>nul
"%ProgramFiles%\Microsoft Office\root\vfs\ProgramFilesX86\Microsoft Office\Office16\DCF\SPREADSHEETCOMPARE.EXE" "tmp.txt"
endlocal
>tmp.txt echo %~2 cannot be used as not working for something like "Hello & welcome!". Windows command processor would interpret the first string separated by normal space, horizontal tab, comma, equal sign, or no-break space (in OEM code pages) delimited string after & as command or application to execute as described by single line with multiple commands using Windows batch file.
"tmp.txt" could be written everywhere in both batch files also with just tmp.txt. But it is never wrong to enclose the complete file/folder argument string in double quotes even on not being really necessary because of the string does not contain a space or one of these characters &()[]{}^=;!'+,`~. So it is good practice to always enclose a complete file/folder argument string in double quotes. For example running a replace on both batch files searching for tmp.txt and using as replace string %TEMP%\%~n0.tmp would result in using instead of tmp.txt in current directory a temporary file with name of batch file as file name and file extension .tmp in directory for temporary files independent on what is the name of the batch file and what is the path of the directory for temporary files.
The last suggestion is reading this answer for details about the commands SETLOCAL and ENDLOCAL.
The temporary file should be also deleted finally before reaching an exit point for batch file execution.
You can use quotes as below:
It treats the string in quotes as a title of the new command window. So, you may do the following:
start "" "yourpath"
Found it in the below link :
https://ccm.net/forum/affich-16973-open-a-file-with-spaces-from-batch-file
There's something I'm not understanding about the way that the batch for command works, when used with /f and a command.
I was trying to loop on the output of an executable. The executable turned out to not exist, which is fine.
But instead of getting the expected error about a bad path, the script seemed to spontaneously incorrectly tokenize the string. This led me down a rabbit hole of thinking that I had formatted the for loop and/or used quotes or back-ticks incorrectly.
Placing an executable at the location fixes the issue, making it appear like the path string tokenizing is dependent on the existence of an actual file at that path.
Why does the following batch file
#echo off
for /f "usebackq delims=" %%i in ( `"C:\Program Files\BOGUS_PATH\FAKE.exe"`) do (
rem
)
output 'C:\Program' is not recognized as an internal or external command, operable program or batch file. instead of The system cannot find the path specified. ?
First off, a pet peeve of mine, the usebackq is not needed. The simpler and functionally equivalent command is
#echo off
for /f "delims=" %%i in ('"C:\Program Files\BOGUS_PATH\FAKE.exe"') do (
rem
)
The only time usebackq is required is when you are trying to read a file, and the file path contains token delimiters like space.
for /f "usebackq" %%A in ('"some file.txt"')
All other situations can use the "normal" forms
for /f %%A in (fileName) do...
for /f %%A in ("string") do...
for /f %%A in ('someCommand') do...
Now to answer your actual question :-)
The presence or absence of the file does not actually alter the parsing.
First you need to understand the possible error messages when you try to execute a non-existent program from the command line. There are three possibilities:
1) If the "command" includes a colon anywhere other than the 2nd position, then you may get the following
c:\test\>abc:fake.exe
The filename, directory name, or volume label syntax is incorrect.
c:\test\>abc:\test\fake.exe
The filename, directory name, or volume label syntax is incorrect.
Or sometimes you get the next possible error. The rules as to which message you get are not obvious to me, and I don't feel like it is important enough to figure out the exact rules.
2) If the "command" includes a backslash that indicates a path, and the path is not valid, then you get
c:\test\>c:bogus\fake.exe
The system cannot find the path specified.
c:\test\>\bogus\fake.exe
The system cannot find the path specified.
c:\test\>abc:bogus\fake.exe
The system cannot find the path specified.
3) If the executable file cannot be found, and either the "command" does not include path info or the provided path is valid, then you get
C:\test\>fake.exe
'fake.exe' is not recognized as an internal or external command,
operable program or batch file.
C:\test>c:\test\fake.exe
'c:\test\fake.exe' is not recognized as an internal or external command,
operable program or batch file.
The last conundrum is why "C:\Program Files\BOGUS_PATH\FAKE.exe" gives error 3) instead of 2)
If you execute from the command line with quotes then you get the expected result:
C:\test>"C:\Program Files\BOGUS_PATH\FAKE.exe"
The system cannot find the path specified.
If you execute from the command line without quotes, then you get this expected result:
C:\test>C:\Program Files\BOGUS_PATH\FAKE.exe
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
Your script includes quotes, so you would expect the former, but you get the latter.
There are two parts to understanding this.
First off, FOR /F executes the command by executing
C:\WINDOWS\system32\cmd.exe /c "C:\Program Files\BOGUS_PATH\FAKE.exe"
You might think your "command" is quoted, but cmd.exe plays games with quotes, which is the 2nd part to the explanation. The cmd.exe quote rules are described in the help:
c:\test\>help cmd
Starts a new instance of the Windows command interpreter
...
If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line, where the following logic is
used to process quote (") characters:
1. If all of the following conditions are met, then quote characters
on the command line are preserved:
- no /S switch
- exactly two quote characters
- no special characters between the two quote characters,
where special is one of: &<>()#^|
- there are one or more whitespace characters between the
two quote characters
- the string between the two quote characters is the name
of an executable file.
2. Otherwise, old behavior is to see if the first character is
a quote character and if so, strip the leading character and
remove the last quote character on the command line, preserving
any text after the last quote character.
Most of the conditions under 1. are met except for the last one - the string does not point to a valid executable. So the 2. rules are used, thus the command becomes
C:\Program Files\BOGUS_PATH\FAKE.exe
And now the result makes perfect sense - the "command" breaks at the space.
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
If you are trying to execute a command with FOR /F, and the command must be enclosed within quotes, then you must put an extra set of quotes around the entire command.
for /f "delims=" %%A in ('""c:\some path\file.exe" "arg 1" arg2"') do ...
But the above will have problems if there are poison characters in the path or quoted argument, because the extra set of quotes mess up the quoting. You could escape the poison characters like
for /f "delims=" %%A in ('""c:\some path\file.exe" "this^&that" arg2"') do ...
But I find that awkward because the command you use on the command line does not match the command you use in a FOR /F. I prefer to escape the extra set of enclosing quotes so that whatever works on the command line also works within FOR /F.
for /f "delims=" %%A in ('^""c:\some path\file.exe" "this&that" arg2^"') do ...
FOR is an internal command of Windows command processor cmd.exe. The usage of command FOR with option /F and a command to execute results in starting with %ComSpec% /c and the specified command line as further parameter(s) one more command process running in background.
Everything output to handle STDOUT is captured by current command process executing the batch file with command FOR and is processed by FOR after termination of additionally started cmd.exe line by line.
The output to handle STDERR of additionally started command process is redirected to handle STDERR of current command process resulting in getting it displayed in console window in case of STDERR is neither in additionally started command process nor in current command process redirected to a different handle, file or device NUL.
This can be seen on using free Sysinternals (Microsoft) tool Process Monitor.
Download the ZIP file containing Process Monitor.
Extract the ZIP file into any local directory.
Start Procmon.exe with Run as administrator which is required to run Process Monitor.
In Process Monitor Filter dialog displayed first Add the entry Process Name is cmd.exe and close the dialog with button OK.
Toggle off the last five options on toolbar with the exception of the filling cabinet symbol with the tooltip Show File System Activity.
Press Ctrl+X to clear the list.
Run the batch file.
Switch back to Process Monitor and press Ctrl+E to stop capturing.
Make sure to see among the column Process Name also the column PID. Right click on list header and left click on context menu item Select Columns... if the PID column is not already displayed, check Process ID and close dialog window with OK. I recommend to move the column PID using drag and drop of column header PID right to column Process Name.
Scroll up to begin of list of captured file system activities and look for the line where a cmd.exe with a different process identifier is displayed than the first one. That second cmd.exe with different PID is the Windows command processor instance started by FOR.
Right click on this second cmd.exe, left click in context menu on Properties, select tab Process and look on Command Line showing:
C:\Windows\system32\cmd.exe /c "C:\Program Files\BOGUS_PATH\FAKE.exe"
Okay. So we know now what FOR respectively cmd.exe does on running a command to capture the output of this command. Close the properties window.
Look on list and it can be seen which file system accesses are made by second cmd.exe to find the specified executable which does not exist in specified and existing directory. It searches next for C:\Program Files\BOGUS_PATH\FAKE.exe.* also with no such file as result.
The first argument string is split up now on argument separators to which belongs the space character among some others like comma or equal sign. So the first argument string C:\Program Files\BOGUS_PATH\FAKE.exe is argument separated once more resulting in interpreting C:\Program now as first argument string.
cmd.exe checks if the directory path being now just C:\ is existing which is true like it was before for directory path C:\Program Files\BOGUS_PATH.
Next is checked if there is a file matching the pattern C:\Program.* which returns no such file. Then cmd.exe checks if there is the file C:\Program which again results in no such file.
Now second cmd.exe gives up finding a file which could be executed and outputs the error message.
It is indeed confusing on having specified the executable with full path enclosed in double quotes as required because of the space to get not output
'C:\Program Files\BOGUS_PATH\FAKE.exe' is not recognized as an internal or external command
operable program or batch file.
This would be expected, but output is the error message:
'C:\Program' is not recognized as an internal or external command
operable program or batch file.
I think, parsing the first argument string once again using the argument separators on not finding a file to execute is done for example if a user runs cmd.exe with the command (argument)
"C:\Programs\MyApplication.exe C:\Temp\FileToProcess.txt"
instead of
"C:\Programs\MyApplication.exe" "C:\Temp\FileToProcess.txt"
So the question is:
Is this automatic argument parsing good or not good?
Well, this is difficult to answer. It is at least somehow documented in help of cmd.exe as described by dbenham in his answer.
What you probably need to do is to enclose your executable command in doublequotes:
#Echo Off
For /F Delims^=^ EOL^= %%A In ('""C:\Program Files\BOGUS_PATH\FAKE.exe""'
)Do Echo(%%A
Pause
Where the inner set of doublequotes is to protect the known space in the path, and the outer set to protect the inner ones when the content is passed to the cmd.exe instance, that the parenthesised command is run in.
Then to prevent any error message from the command, you should redirect the STDERR output to NUL:
#Echo Off
For /F Delims^=^ EOL^= %%A In ('""C:\Program Files\BOGUS_PATH\FAKE.exe" 2>Nul"'
)Do Echo(%%A
Pause
If the executable does not exist, this will supress the error message, The system cannot find the path specified. and the Do command will not run, (as there is no STDOUT to process).
I'm building a script for Windows command line in which I try to check some filenames in a FOR loop, and then stripping off part of the filename into a variable for further use. Basically, what I want to happen is this:
List all files in a certain directory, splitting of the extension like .osm.pbf in this case.
Assign the filename to a variable.
Out the last 7 characters of the filename in another variable.
Compare this new variable to "-latest".
If the compare is true, cut a part of the variable containing the filename.
If the compare is false, take over the complete variable into another variable.
Through some trial and error and some searching online, I've arrived at this point (which still isn't doing what I want):
FOR /F "tokens=1-2 delims=." %%M IN ('DIR /b %VECTOR_WORKDIR%\*.osm.pbf') DO (
SET VECTOR_CURRENT_MAP2=%%M
ECHO !VECTOR_CURRENT_MAP2! >> %VECTOR_LOGFILE%
SET LAST_BIT_TEMP=!VECTOR_CURRENT_MAP2:~-7!
ECHO !LAST_BIT_TEMP! >> %VECTOR_LOGFILE%
SET LAST_BIT=!LAST_BIT_TEMP: =!
ECHO !LAST_BIT! >> %VECTOR_LOGFILE%
IF !LAST_BIT!=="-latest" (
SET VECTOR_CURRENT_MAP3=!VECTOR_CURRENT_MAP2:~0,-8!
ELSE
SET VECTOR_CURRENT_MAP3=!VECTOR_CURRENT_MAP2!
)
ECHO !VECTOR_CURRENT_MAP3! >> %VECTOR_LOGFILE%
)
This results in these lines in the log file, for the file basse-normandie-latest.osm.pbf:
basse-normandie-latest
-latest
-latest
ECHO is on.
The first echo is correct, although the filename has a trailing space. (So actually it's "basse-normandie-latest ".)
The second echo doesn't seem to take this training space into account, as it correctly gives "-latest" as the last 7 characters. This echo also has a trailing space (So actually it's "-latest ".)
The third echo is an attempt to clear the spaces from the variable (by using ": ="), but this results in another trailing space. (So actually it's "latest ".)
The final echo after the IF statement (where I try to cut the "-latest" part from the filename), results in "ECHO is on".
I have SETLOCAL enabledelayedexpansion enableextensions declared at the top of my script.
Any thoughts on how to make this work, i.e. get rid of the trailing spaces to make the comparison work?
Thanks in advance for any pointers in the right direction!
A line like
ECHO !VECTOR_CURRENT_MAP2! >> %VECTOR_LOGFILE%
results in appending the value of the environment variable VECTOR_CURRENT_MAP2 to file with file name stored in environment variable VECTOR_LOGFILE with a trailing space because there is a space before redirection operator >> which is interpreted by Windows command processor as part of the string to output by command ECHO. This space must be removed to get the file name redirected into the log file without a trailing space.
In general it is critical on redirecting a variable string into a file without a space between the variable string and the redirection operator in case of the variable string ends with a space and a number being a valid handle number like 1 or 2 or 3. There are several solutions to workaround this problem like specifying the redirection left to command ECHO, i.e.
>>%VECTOR_LOGFILE% ECHO !VECTOR_CURRENT_MAP2!
But on using delayed expansion as simply necessary here, it is safe to append the redirection at end without a space between exclamation mark and >>, i.e.
ECHO !VECTOR_CURRENT_MAP2!>> %VECTOR_LOGFILE%
The space after redirection operator is ignored by Windows command processor and therefore can be kept although many batch file programmers (like me) with good syntax highlighting don't insert a space after a redirection operator.
On comparing strings with command IF and enclosing one string in double quotes which is always a good idea, it must be made sure that the other string is also enclosed in double quotes. The command IF does not remove the double quotes before comparing the strings. The double quotes are parts of the compared strings.
The condition
IF !LAST_BIT!=="-latest"
is only true if the string assigned to environment variable LAST_BIT would be with surrounding quotes which is never the case with your batch code and therefore the condition is never true.
Correct would be:
IF "!LAST_BIT!"=="-latest"
There is no need to use command DIR to search for files with a pattern in a directory as command FOR is designed for doing exactly this task. Processing of output of command DIR is an extension of FOR available only if command extensions are enabled as by default.
The file extension is defined by Microsoft as everything after last dot in name of a file. Therefore the file extension for your files is pbf respectively .pbf and .osm belongs to the file name.
Command FOR offers several modifiers to get specific parts of a file or directory name. Those modifiers are explained in help output into console window on running in a command prompt window for /?. Help of command CALL output with call /? explains the same for processing parameters of a batch file or subroutine (batch file embedded within a batch file).
Your code with all mistakes removed:
FOR %%M IN (*.osm.pbf) DO (
SET "VECTOR_CURRENT_MAP2=%%~nM"
SET "VECTOR_CURRENT_MAP2=!VECTOR_CURRENT_MAP2:~0,-4!"
ECHO !VECTOR_CURRENT_MAP2!>>%VECTOR_LOGFILE%
SET "LAST7CHARS=!VECTOR_CURRENT_MAP2:~-7!"
ECHO !LAST7CHARS!>>%VECTOR_LOGFILE%
IF "!LAST7CHARS!" == "-latest" (
SET "VECTOR_CURRENT_MAP3=!VECTOR_CURRENT_MAP2:~0,-7!"
) ELSE (
SET "VECTOR_CURRENT_MAP3=!VECTOR_CURRENT_MAP2!"
)
ECHO !VECTOR_CURRENT_MAP3!>>%VECTOR_LOGFILE%
)
Easier would be using this code with using string substitution feature of command SET, i.e. search within a string case-insensitive for all occurrences of a string and replace them with another string which can be also an empty string.
FOR %%M IN (*.osm.pbf) DO (
SET "VECTOR_CURRENT_MAP2=%%~nM"
SET "VECTOR_CURRENT_MAP2=!VECTOR_CURRENT_MAP2:~0,-4!"
ECHO !VECTOR_CURRENT_MAP2!>>%VECTOR_LOGFILE%
SET "VECTOR_CURRENT_MAP3=!VECTOR_CURRENT_MAP2:-latest=!"
ECHO !VECTOR_CURRENT_MAP3!>>%VECTOR_LOGFILE%
)
%%~nM is replaced on execution by Windows command processor by the name of the file without drive, path and file extension resulting for your example in basse-normandie-latest.osm.
The unwanted file name part .osm is removed with the next line in both batch code blocks which chops the last 4 characters from the file name string.
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 /?
for /?
if /?
set /?
Read the answer on question Why is no string output with 'echo %var%' after using 'set var = text' on command line? for an explanation why I used set "variable=value" on every line which assigns a value string to an environment variable because trailing whitespaces are critical for your task.
What am I missing?
#echo off
rem - processfiles.bat - Processes all text files in the "source" folder:
rem - Runs %executable% with each text file as parameter
rem - Move the text file to the target folder after processing
set SourceFolder=C:\Users\Chris\Desktop\Yield_Files
set TargetFolder=C:\Users\Chris\Desktop\YieldCleanFiles
set fin=default.set
if not exist "%TargetFolder%" md "%TargetFolder%"
echo Processing text files in %SourceFolder%:
for %%f in (%SourceFolder%\*.txt) do call "C:\Program Files\Yield_Editor\yieldeditor.exe/csvin="(%SourceFolder%\*.txt)"/auto="y"/hide/fin=%fin%"%%f
pause
I have to have the file name I am working on each time I call the .exe
when ran it says it cannot find the file specified, but I am not sure which one it is talking about.
The line
for %%f in (%SourceFolder%\*.txt) do call "C:\Program Files\Yield_Editor\yieldeditor.exe/csvin="(%SourceFolder%\*.txt)"/auto="y"/hide/fin=%fin%"%%f
must be written most likely
for %%f in ("%SourceFolder%\*.txt") do "C:\Program Files\Yield_Editor\yieldeditor.exe" /csvin="%SourceFolder%\*.txt" /auto=y /hide /fin=%fin% "%%~f"
or
for %%f in ("%SourceFolder%\*.txt") do "%ProgramFiles%\Yield_Editor\yieldeditor.exe" "/csvin=%SourceFolder%\*.txt" /auto=y /hide /fin=%fin% "%%~f"
which means your executable must be run with syntax
"Path to Application\Application.exe" "/First Option" /Option2 /Option3 /Option4 "File Name As Fifth Parameter"
File name of application with file extension and path must be in quotes if there is at least 1 space or another character with a special meaning which are output in a command prompt window on last help page displayed when running in command prompt window cmd /?. This is argument 0 for the application.
The first parameter/option is argument 1 for the application. It must be in quotes if the parameter string contains a space or another special character. Options not containing a space must not be quoted, but can be nevertheless also quoted.
Some applications support quoting inside an option with a variable string. An example for such a syntax would be /csvin="%SourceFolder%\*.txt".
Read the help/documentation of the application for details on using it from command line. Most Windows console applications can be executed from within a command prompt window with just /? as parameter for printing command line help to console.
It can be seen here why argument strings with spaces must be enclosed in quotes. The space is the separator for the arguments.