escape special character (%) - batch-file

i have a command that displays the current name of the batch file that it's code is appended to.
echo %~n0%~x0
i want to send the command to a text file without changing its syntax.
for example;
echo %~n0%~x0 >> somefile.txt
i tried escaping the percentage sign with another percentage but it doesn't work.
echo %%~n0%%~x0
any ideas...?

Try the caret instead of the %% like this ^% you might also need to escape the escape (I know weird and why .. but ..you might).
Using the CARET ^ worked for me.
echo ^%%~n0^%%~x0 >> somefile.txt
this code will produce the batch file name
echo ^%~n0^%~x0 >> somefile.txt

Related

How to write a pipe (|) in batch file from another batch file?

I am trying to make .bat script from another .bat script where I have to insert a command which has pipe | in it. When I executed the main script I got an error. I tried to figure it out by putting "|" or making whole command in between quotes, "command".
Escape the character | using caret ^
As an example, here is a batch-file called dummy.cmd which needs to create another batch file called ping_script.cmd
#(echo ping localhost ^| findstr /i "reply")>ping_script.cmd
You can also do numerous outputs to the file. Here is the same script, but it also adds a line to echo test newline script. Here you will see that the special character is also being escape, else the first batch file will see it as an operator for itself. Below that, it can still do whatever is needed in the first script, like testing if ping_script.cmd exists.
#(echo ping localhost ^| findstr /i "reply"
echo echo Test ^& echo Script
)>ping_script.cmd
if exist ping_script.cmd echo Success
Note, not all special characters can be escaped using caret. This link at Rob van Der Woude shows a decent table.

batch script to make batch script

ok simple i want to make a batch script that:
Makes export folder on users desktop
from new (as in not copying from somewhere) make a batch script in that folder that lists the contents of that folder after the user populates it and saves it to the desktop.
the problem i run in to is I'm trying to use echo to to copy the intended new script text from the original batch file into the new one like this:
#echo off
mkdir "C:\Users\%username%\Desktop\Export"
echo dir "C:\Users\%username%\Desktop\Export" /W /A:-H /B > "C:\Users\%username%\Desktop\Readout.txt" > "C:\Users\%username%\Desktop\Export\Directoty_List.bat"
the problem is that the echo command sees the ">" as the end of the statement and writes the first part to a desktop text file, but i want it to see the 2nd ">" as that. how do i work around this?
Thank you
As #Richard said in the comments, you can escape the > with a carret sign ^>. Most characters with special meaning in cmd can be escaped with the carret if you don't want to use that special meaning.
Normally the golden rule is: put everything between double quotes. Inside double quotes, the characters with special meanings are also escaped. Unfortunately the echo will print the quotation marks too so this won't really help in your case. It still is worth mentioning though, quotation marks help when setting values of variables with special characters, passing arguments with special characters, define paths with special characters (whitespaces or parenthesis for eg.), ... but not with echo.
There is one more advice I'd like to give: you can use %userprofile% instead of specifying the whole path C:\Users\%username%
#echo off
mkdir "%userprofile%\Desktop\Export"
echo dir "%userprofile%\Desktop\Export" /W /A:-H /B ^> "%userprofile%\Desktop\Readout.txt" > "%userprofile%\Desktop\Export\Directoty_List.bat"

Stripping part of a filename and using it for a comparison

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.

Escape special character in a windows batch

I have a batch file that receive a path as first argument. The path is always composed with specials characters like ^,é or è.
The call is similar to this
D:\Script>MyBatch My\path\test_00170_LASTNAME^Firstname\image
There is always this error: unknown specified path
When I echo the first argument in my bash I can see (notice the missing ^)
My\path\test_00170_LASTNAMEFirstname\image
So I tried to escape this character by adding another ^ just before
My\path\test_00170_LASTNAME^^Firstname\image
But when I echo this one, I have the same result ...
My\path\test_00170_LASTNAMEFirstname\image
I also tried to put the ^ between quotes but this did not work
You need to escape the caret signs at the command line or better put the path into quotes.
In both cases you should work with delayed expansion, as then the content will not be modified when it is expanded.
myBatch "C:\LASTNAME^Firstname\image"
or
myBatch C:\LASTNAME^^Firstname\image
And in your batch use swomething like this
#echo off
set "arg1=%~1"
setlocal EnableDelayedExpansion
echo !arg1!
You need to escape it twice - once when you input the path as an argument to the batch script, and again when echo'ing it:
caret_input.bat:
echo %1
Double-escaped (notice how it's already escaped when the batch file starts outputting):
C:\>caret_input.bat my\path^^^^is\special
C:\>echo my\path^is\special
my\path^is\special
If you were to use a string with a special character inside the batch file, your method of escaping it just once would work just fine:
caret_escape.bat:
echo my\path^^is\special
and the output
C:\>echo my\path^is\special
my\path^is\special

Use a batch file to write txt to another file

How would i add this text to a file because it seems to get confused with the other greater than less than signs thanks
echo >> C:\docs\thisdoc.txt
If I've got you right, you want to write the text "echo >> c:\docs\thisdoc.txt" in a file? Then you need to escape the ">"characters with "^":
echo echo ^>^> C:\docs\thisdoc.txt > mybatch.cmd

Resources