Single letter variables in cmd - variables

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.

Related

Recursively search directory for occurrences of each string from one column of a .csv file

I have a CSV file--let's call it search.csv--with three columns. For each row, the first column contains a different string. As an example (punctuation of the strings is intentional):
Col 1,Col 2,Col 3
string1,valueA,stringAlpha
string 2,valueB,stringBeta
string'3,valueC,stringGamma
I also have a set of directories contained within one overarching parent directory, each of which have a subdirectory we'll call source, such that the path to source would look like this: ~/parentDirectory/directoryA/source
What I would like to do is search the source subdirectories for any occurrences--in any file--of each of the strings in Col 1 of search.csv. Some of these strings will need to be manually edited, while others can be categorically replaced. I run the following command . . .
awk -F "," '{print $1}' search.csv | xargs -I# grep -Frli # ~/parentDirectory/*/source/*
What I would want is a list of files that match the criteria described above.
My awk call gets a few hits, followed by xargs: unterminated quote. There are some single quotes in some of the strings in the first column that I suspect may be the problem. The larger issue, however, is that when I did a sanity check on the results I got (which seemed far too few to be right), there was a vast discrepancy. I ran the following:
ag -l "searchTerm" ~/parentDirectory
Where searchTerm is a substring of many (but not all) of the strings in the first column of search.csv. In contrast to my above awk-based approach which returned 11 files before throwing an error, ag found 154 files containing that particular substring.
Additionally, my current approach is too low-resolution even if it didn't error out, in that it wouldn't distinguish between which results are for which strings, which would be key to selectively auto-replacing certain strings. Am I mistaken in thinking this should be doable entirely in awk? Any advice would be much appreciated.

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

Batch Scripting Help - Replace Substring of a DelayedExpansion Var with another DelayedExpansion Var

Basically I'm trying to do !var1:SomeText=!var2!! but this code doesn't work.
What am I missing?
The order of expansion is critical when doing a search and replace operation that uses a variable for the search and/or the replace. The inner variable must be expanded before the outer search and replace expansion takes place. Trying to used delayed expansion for both obviously can't work because the delayed expansion occurs at one point in time.
The classic method for expansion of a variable within another variable uses delayed expansion for the outer, and normal for the inner: echo !var1:SomeText=%var2%!"
I am going to assume you wanted to use delayed expansion for both for a reason. Perhaps the expansion occurs within a block of code and one of the variables was set in the same block. Normal expansion won't work because it can't see the value that was assigned within the block until after the block concludes.
Solution 1
One way to solve the problem is to use CALL:
call echo %%var1:SomeText=!var2!%%
This works as follows:
The percent phase of the parser converts double percents into single percents, resulting in
call echo %var1:SomeText=!var2!%
The delayed expansion expands !var2!, resulting in
call echo %var1:SomeText=ReplacementText%
The CALL ECHO is executed and an additional level of percent processing takes place. The search and replace expansion is executed, resulting in ResultOfSearchAndReplace being echoed to the screen.
This works, but it is relatively slow. It also can have problems if the expanded value has special characters like >, & or |. I rarely use this technique.
Solution 2
The fast and more reliable method is to do the expansion in two steps. First transfer the value of !var2! to a FOR variable. You can then use the FOR variable as the replacement string and use delayed expansion for the second step. This completely avoids the more brittle percent expansion.
for /f "delims=" %%A in ("!var2!") do echo !var1:SomeText=%%A!
The above works because FOR variable expansion takes place before delayed expansion.
This is by far my preferred method to attack this problem.
For a more thorough explanation of the various phases of the batch parser, refer to jeb's answer to How does the Windows Command Interpreter (CMD.EXE) parse scripts?

Adding numbers containing commas in a batch script

I'm trying to add two numbers together in a windows batch file. The numbers are coming from the output of a command and I cannot change the code to output it in a different format.
The problem is that the numbers use commas in the numbers as the thousands separator. i.e. 154022 is output as 154,022. Now when I try to add this number to another number it only adds the first part (i.e. that 154).
set A=1,000
set B=154,022
set /a TOTAL=A + B
echo %TOTAL%
produces: 155, not 155022 that I would like, or even 155,022 would do.
Is there a way to convert easily from numbers with commas to numbers without commas in a batch script?
set A=1,000
set B=154,022
set A2=%A:,=%
set B2=%B:,=%
set /a TOTAL=A2 + B2
echo %TOTAL%
You can do string manipulation like this
set result=%input:substring=replacement%
This one and other nice tips: http://www.dostips.com/DtTipsStringManipulation.php