Batch file; Replace variable's spaces with hyphens - variables

I've started another small Batch project, however I've encountered a bit of a dilemma. I use set name= followed by set /p name=, to allow the user to give the input desired. However, I want the variable entered with spaces to then have the spaces replaced with hyphens (e.g. "hello world" becomes "hello-world").
I've searched around and found many situations in which someone asks a similar question, however they are all using the ren command, which I have no use for due to not dealing with files.
My current code is as follows:
#echo off
Cls
echo Insert a string with spaces?
set string=
set /p string=
I have also found a solution for renaming files that mentioned using ren "!file!" "!file:_= !" to change a file name's spaces to underscores (_). However changing it to set name=!name:-= ! didn't work for me.
How can I best replace spaces with hyphens in my batch file?

You're close.
#echo off
cls
echo Insert a string with spaces?
set string=
set /p string=
set string=%string: =-%
echo String is now %string%
See set /? for details on variable manipulation.

Related

Issue with special characters in path (exclamation point !, carrot ^, etc) using batch Delayed Expansion

I have looked around and not been able to find anything to get my script working correctly with special characters (such as ! or ; or ^) in the file path or file name.
My script does work, but only if the above characters are not in any of the scanned folders or file names. If any folders or files have those characters, then the script breaks down. I need help figuring out how to make my script work with special characters (like above) within the path or file name. Here is my script:
set srcdir=%~dp0%src
set desdir=%~dp0%des
setlocal EnableDelayedExpansion
for /r "%srcdir%" %%f in ("*.txt") do (
set "subdir=%%~f"
set "subdir=!subdir:%srcdir%=%desdir%!"
echo !subdir!
pause
)
endlocal
Thanks for any and all assistance!
Exclamation marks get clobbered when delayed expansion is enabled while you set a variable. You can avoid this by waiting to delay expansion until you retrieve a variable value. Sometimes this takes some acrobatics to make it work. In this case, it's probably easier just to leave delayed expansion disabled and use call to delay expansion.
#echo off
setlocal
set "srcdir=%~dp0%src"
set "desdir=%~dp0%des"
for /r "%srcdir%" %%f in ("*.txt") do (
set "subdir=%%~f"
rem // use call to avoid delayed expansion and preserve exclamation marks
call set "subdir=%%subdir:%srcdir%=%desdir%%%"
rem // use set /p rather than echo to exploit quotation marks and preserve carets
call set /P "=%%subdir%%"<NUL & echo;
pause
)
Or if you prefer delayed expansion, one trick I like to use to toggle delayed expansion for one line is to use a for loop like this:
#echo off
setlocal
set "srcdir=%~dp0%src"
set "desdir=%~dp0%des"
for /r "%srcdir%" %%f in ("*.txt") do (
set "subdir=%%~f"
setlocal enabledelayedexpansion
for %%I in ("!subdir:%srcdir%=%desdir%!") do endlocal & set "subdir=%%~I" & echo(%%~I
pause
)
Put all paths in between "".
Always use syntax set "VAR=Value".
Toggle delayed expansion: when expanding %%~F, disable it; afterwards, enable it.
Here is the fixed code:
setlocal DisableDelayedExpansion
set "srcdir=%~dp0src"
set "desdir=%~dp0des"
for /R "%srcdir%" %%F in ("*.txt") do (
set "subdir=%%~F"
setlocal EnableDelayedExpansion
set "subdir=!subdir:%srcdir%=%desdir%!"
echo(!subdir!
pause
endlocal
)
endlocal
This only works as long as the directory where the batch file is stored does not contain exclamation marks. If it does, let me know...
Amendment
Sub-string substitution using also variables for the search and replace strings is never safe against all characters in general.
Imagine you have something like this:
echo(!VAR:%SEARCH%=%REPLACE%!
This means to replace every occurrence of %SEARCH% by %REPLACE% (in a case-insensitive manner).
But if %SEARCH% contains a =, the behaviour is changed: for instance, %SEARCH% is a=b and %REPLACE% is cd, the immediately expanded version is !VAR:a=b=cd!, so every a is going to be replaced by b=cd.
A leading * in %SEARCH% changes the behaviour: replace everything up to and including the rest of %SEARCH% by %REPLACE%. (An asterisk cannot occur within a path, of cource.)
A leading ~ in %SEARCH% changes the the behaviour from sub-string substitution to sub-string expansion, that is, expansion of a string portion given by character position an length; if the syntax is violated, the non-expanded string !VAR:~a=b! will be returned literally, supposing ~a and b are the search and replace strings, respectively.
Finally, if %SEARCH% and/or replace contain a !, this is going to be taken as the closing ! for the delayed expansion, so !VAR:a!=b! is seen as !VAR:a!, which is invalid syntax and will be kept as is.

Need clean syntax in batch

Context
I am thinking I can solve a problem with the proper creation of a *.bat file.
I am automating a process in a backup program called Acronis Backup and Recovery.
I am able to make a script (jScript) that creates all the syntax except for one part correctly.
In a normal command prompt the command I would run looks like this
acrocmd backup file --include="C:\documents\Gale_thesis.doc" "D:\Sandbox\!oDC!-IMG_0222.MOV" "C:\temp\magnifyReader" --loc="D:\backups" --arc="Backup1a"
The jScript I am creating can generate this with no problem and save as a *.bat file. This can works perfect if my file names are clean. By clean I mean no characters the batch files think are key words and commands.
Anytime I have a word like “copy” or a character like “!” in a file name it fails.
Question
So I am now wondering if loading variables from a text file would do the trick?
I am sure a lot of readers know that when load multiple file/folder paths at the command line you need to surround them with double quotes.
So I need this variable to have the correct syntax to be parsed by the batch file and work like the example when I type it directly at a command prompt.
I had tried to follow info about using for /f etc.
But the examples are not broad enough for me to understand, nobody seems to explain how to use these variables mixed in with other syntax.
I know a little about working with variable in a *.bat file. My jScript application can produce the text in any format a list, escaped, what ever is needed.
Thanks
I might suggest you to take a look at escaping characters
http://www.robvanderwoude.com/escapechars.php
in for loops !var! is used when delayedexpansion is enabled so you might need to escape it
I used the following code provided by Aacini to test the arguments that are being passed
#echo off
setlocal enabledelayedexpansion
set argCount=0
for %%x in (%*) do (
set /A argCount+=1
set "argVec[!argCount!]=%%~x"
)
echo Number of processed arguments: %argCount%
and since delayedexpansion is enabled I had to escape ! character
arg.bat --include="C:\documents\Gale_thesis.doc" "D:\Sandbox\^^^!oDC^^^!-IMG_0222.MOV" "C:\temp\magnifyReader" --loc="D:\backups" --arc="Backup1a"
Also about the triple escape quotes ^^^
the problem here is that we need to pass two special characters,
1st is the up arrow ^ and 2nd is the exclamation mark !
so the 2nd batch file (the one that reads our arguments) should get ^!
to escape ^ we use ^^ and to escape ! we use ^!
Thanks to Aacini for his code in HERE

Single letter variables in cmd

Apologies for a silly and newbie question, but I have no IT background whatsoever, and I don't seem to be able to find an answer in google for that.
I am currently trying to understand (very) simple batch script which happens to be:
for /F "tokens=1,2,3 delims=," %%i in (users.csv) DO dsadd user "cn=%%j
%%i %%k,ou=2013,ou=students,dc=[domain],dc=org"
The bits that is unclear for me are %%i, %%j, %%k. I can see that they represent the columns from the csv file, respectively 1,2,3, and that the output is in the order 2,1,3.
Now, my question is - are letters i, j, k for variables fixed? I can see that this works when I replace them with a, b, c respectively, so I guess not. So is it an agreed convention?
I guess that %%i in this bit delims=," %%i in (users.csv) determines what letter should correspond to the first token, and then the following tokens are assigned alphabetically to j and k?
The following attributes apply to the for command:
The for command replaces %variable or %%variable with each text string in the specified set until the command processes all of the files.
For variable names are case-sensitive, global, and no more than 52 total can be active at any one time.
To avoid confusion with the batch parameters %0 through %9, you can use any character for variable except the numerals 0 through 9. For simple batch files, a single character such as %%f works.
You can use multiple values for variable in complex batch files to distinguish different replaceable variables.
For - http://technet.microsoft.com/en-us/library/bb490909.aspx
The first letter defined will be the first token with the remaining tokens being the next letters alphabetically.
Type the command for /? for more details.

Special Characters in a Variable

I have searched for an way to pass on the special characters located in a string but cannot find anything relevant. Currently the string is concatenated at the first special character.
for /D /R "%cd%" %%d IN (*) do (call :Write_File "%%~nd")
Can escape character be used or will I need a for loop to substitute the special characters, and another to replace them?
The variable is supposed to return the folder name. It returns the full length string unless it contains a special character %, &, ,, ., etc.
at which point it returns everything up until that point. Example B&B returns B, where as I require it to return B&B.
With three example folder named: "%$", "01, Copy" and 03&
echoing the variable as it reads it (&&echo "%%~nd"): "$%", "01, Copy" and misses the third
Renaming the variable within :Write_File (set "FOLDER=%~1"): "$", "01, Copy"
Edit for clarification:
Special Characters: %, $, &, *, ~, etc.
Use: When echoing the folder names
Sometimes it misses the special character, sometimes it skips the folder entirely.
You can't use CALL here with the value, instead use a reference to a variable.
for /D /R %%d IN (*) do (
set "myDir=%%~nd"
call :Write_File myDir
)
exit /b
:Write_File
setlocal EnableDelayedExpansion
set "param1=!%1!"
echo !param1!
endlocal
exit /b

Inserting a variable from a batch file into a text file

How would I insert a variable previously established in a batch file into a text file. I have the inserting text into a text file down, i just cant figure out the insertion of a variable.
What I am doing
SET name = "Casey"
ECHO "Hey" + name > file.txt
The result
"Hey" + name
What I want
"Hey Casey"
You should do it like this:
SET name=Casey
ECHO "Hey %name%" > file.txt
Note that there is no spaces before and after the = in
name=Casey
Too bad syntax, you need to forget other programming languages, this is Batch.
First you can't use spaces when assing values to variables, this is the way to do it:
SET "name=Casey"
Also you can do this:
SET "name= Casey"
Second Batch don't have ANY concatenate operator for strings, forget + and &, & is for concatenating commands.
So this is the correct syntax:
SET "name=Casey"
(ECHO Hey %name%)> "file.txt"
Try to use () agrupation operators when Echo a numeric ending string like "MyName 2", to avoid problems in large scripts with Batch redirections.