batch script to make batch script - batch-file

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"

Related

how to make batch file handle spaces in file names

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

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.

Batch Rename Multiple Files?

Similar question to these have been tons of time but, for what i want it is something different. I have tried searching but, not what I want.
Now I have certain (.txt) files in my folder (hidden-files) where certain text files (Multiple text files) are stored which have special characters (%!=^";#% ..etc) in them I would like to remove these special characters and replace them with (-) in a rename loop so the file(s) will be renamed.
Code (Got it from here somewhere) Edited to my use but, it didn't worked.
for /f "delims=" %%a in ('dir "%~dp0hidden-files\*.txt"') do (set "newname=%~nx1"
set "newname=%newname:!=-%"
set "newname=%newname:_=-%"
set "newname=%newname:==-%"
set "newname=%newname:%=-%"
echo ren "%%a" "!newname!")
Would appreciate any help. Cheers.
You have a whole host of problems with your code. I'm too tired to list them all, but there is one issue that is extremely difficult to solve with pure batch - there is no simple way to replace an = literal within a string using batch. The simplest (and perhaps most effective) way to accomplish this is to look character by character for the = and replace it via substring operations.
There are a bunch of other issues that require advanced batch techniques to solve.
I have a much simpler solution for you - my JREN.BAT utility uses regular expression replacement to rename files. It is a hybrid JScript/batch script that runs natively on any Windows machine from XP onward. Use jren /? from the command line to access the built-in help. You might want to use jren /? | more to see one screen at a time. I never use MORE because my console is configured with a large buffer that lets me scroll up to see past output.
Once you have JREN.BAT on your machine, preferably in a folder that is within your PATH variable, then all you need is the following to rename the files within the current directory - no additional batch script required:
jren "[!_=%]" "-" /fm *.txt
If needed, you can specify the folder as an option:
jren "[!_=%]" "-" /fm *.txt /p "c:\YourPathHere"
If you put the command within another batch script, then you will need to use CALL JREN, and the percent needs to be double escaped as %%%%. Percent literals must be escaped as %% within batch files, and the CALL requires an extra round of escape:
#echo off
call jren "[!_=%%%%]" "-" /fm *.txt /p "%~dp0hidden-files"
Update in response to comment
Adding (, ), [, and ] to the list of characters to replace is simple. The only trick is you must escape the ] as \] when it appears within a character set [....].
#echo off
call jren "[!_=%%%%[\]()]" "-" /fm *.txt /p "%~dp0hidden-files"
The other option is to place the ] immediately after the opening [.
#echo off
call jren "[]!_=%%%%[()]" "-" /fm *.txt /p "%~dp0hidden-files"
Regular expressions are incredibly powerful, but they can be confusing to the uninitiated. Use jren /?regex to access Microsoft's help page on all the supported regular expression syntax. There are loads of tutorials available on the internet, as well as web sites that allow you to conveniently test out regular expressions.
If you are developing a JREN command, I suggest you first use the /t option to test it out without actually renaming anything.
Last update for question in comment
File names cannot contain *, ?, |, <, >, \, /, : or ", so you don't need to worry about those characters. I'm not sure what you did, but I don't see the enclosing [...] to represent a character set. The following should work fine:
call jren "[`~!##$%%%%^&_ +=,';}{[\]()]" "-" /fm *.txt /p "%~dp0hidden-files"

Batch file - Using all filepaths in a directory

Im trying to run the following code to go through a directory and modify a bunch of autoCAD drawings.
FOR %%f in (C:\Users\pzf6bm\Desktop\AutoCad\*.dwg) do start /wait C:\"Program Files"\"Autodesk"\"AutoCAD 2012 - English"\acad.exe “%%f” /b C:\Users\pzf6bm\Desktop\AutoCad\hide.scr
It almost works except for one thing, everytime it retrieves the next filepath it adds an ô character to the beginning of the string and a ö to the end of the string. This makes autoCAD not able to open the file to perform the action.
As an example "C:\test.txt" becomes "ôC:\test.txtö" I have no idea why this happens.
just use right double quotes, not “%%f”!
"%%f"
You have smart-quotes around your %%f (perhaps you got this from Outlook or Word?). Retype them as regular quotes and your ô and ö will be gone.
EDIT: Normally the start command needs a blank set of quotes after it, because the first set of quotes is used as the window title. In your case the fact that c:\ is an unquoted part protects the quoted portions. Thanks to #dbenham for pointing that out.
Your command (after the start "" ) has quotes in an awkward mix, where they should normally be placed at the beginning and end of the "c:\path\filename.exe" so see my answer below, with a leading set of blank quotes too.
With modern tools even a short path and filename can be quoted, so it is easy to remember - just quote all terms.
FOR %%f in (C:\Users\pzf6bm\Desktop\AutoCad\*.dwg) do start "" /wait "C:\Program Files\Autodesk\AutoCAD 2012 - English\acad.exe" "%%f" /b "C:\Users\pzf6bm\Desktop\AutoCad\hide.scr"

Simple batchscript breaks when drag&drop a file with an underscore in its filename

I have this simple batchscript...
#ECHO OFF
:batch
IF "%~1"=="" GOTO end
ECHO video=FFVideoSource("%~f1")>"%~f1.avs"
ECHO audio=BassAudioSource("%~f1")>>"%~f1.avs"
ECHO AudioDub(video,audio.TimeStretch(pitch=432.0/4.4))>>"%~f1.avs"
SHIFT
GOTO batch
:end
which when executed from command prompt works fine in all cases, but breaks when I drag&drop a file with an underscore in its filename. Several avs-files are created. I've found them in %~1 its parent directory and even in "C:\Documents and Settings\Admin".
Does anyone know why an underscore would be an issue for drag&drop?
I'm on WinXP, that doesn't have anything to do with it, does it?
The problem is the name of the directory, in this case the commas are the problematic characters.
When drag&drop a file, it will only be quoted when a space is found in the name.
But in this case the commas will split the name into multiple arguments.
D:\Audible[..power progressive symphonic gothic..]\Videos\test_-_test.mp4
In this case you could use %* to access the original fullname, but in some other cases (when a & is in the name) you need a more complex solution.
SO: Drag and drop batch file for multiple files?

Resources