How to replace a line inside a bat file using a command line parameter string

I have the following in the cmd batch file:

for /f %%l in (%2) do (for %%f in (%%l) do copy "%%f" %1)) 

Note: in this case, the script reads a text file containing a comma delimited txt file whose path is set to% 2 (for example, which contains c: \ test1 \ file1.cs; d: \ file2.js) and copy the files to the destination folder specified by% 1.

I need to replace the string value %1 parameter x (which is also passed to the batch file, for example %3 ), with the %4 value, which is also passed as the parameter to the batch file.

eg:

 if %1 = 'test replace x with y' %3=x %4=y 

so the output should be "test replace y with y"

How can I achieve this using the Windows CMD Batch Interpreter?

+12
command-line windows scripting batch-file
Apr 28 2018-11-11T00: 00Z
source share
3 answers

First of all, you will need to save %1 in a variable, after which you will be able to make replacements.

Basically, the replacement syntax is as follows:

 % variable : str1 = str2 % 

which means: "replace each str1 with variable with str2 '.

In your case, both str1 and str2 are parameters, not literal strings. Using the above template directly, you can get this expression:

%variable:%3=%4% .

But this would confuse the parser, since it would not know that %3 and %4 should be evaluated first. In fact, first try to evaluate %variable:% (and fail).

One solution in this case may be to use a method called a "lazy" deferred estimate. Basically, you pass the command in which you evaluate the variable to the CALL command. Converting the original command to its "CALL version" looks like this:

ECHO %var% ==> CALL ECHO %%var%% .

Note the double % s. During parsing, they are evaluated to one % s. The resulting command will be parsed by CALL again, and the final effect will be the same as with the original ECHO %var% command.

Thus, it works the same as the original command (which is good), and what we get here is a later point in the evaluation, I mean the final evaluation, when the variable is actually replaced by its value. Knowing this effect, we can construct our expression so that %3 and %4 evaluated first, and then the entire expression obtained. In particular, like this:

 %%variable:%3=%4%% 

After the first analysis, this expression will look something like this:

 %variable:x=y% 

This will be parsed again, and the output will be variable contents changed.

For a better illustration, here is a simple working example:

 SET "output=%1" CALL SET output=%%output:%3=%4%% ECHO %output% 



UPDATE

There is another way to do the same thing that I probably should have mentioned first.

The Windows command shell supports proper slow expansion. It is easier to use, but has some caveats.

First, how to use it. Syntax for slow expansion !var! instead of %var% for immediate expansion (which remains valid and can be used in conjunction with slow expansion syntax).

Probably !var! will not work in your script until you enable the syntax with the command:

 SETLOCAL EnableDelayedExpansion 

The ENDLOCAL command closes the block in which the extension-delay syntax is valid and is interpreted by the shell.

The above script example can be rewritten as follows:

 SET "output=%1" SETLOCAL EnableDelayedExpansion SET output=!output:%3=%4! ECHO !output! ENDLOCAL 

So, how does this work in the case of the SET output=!output:%3=%4! command SET output=!output:%3=%4! :

  • %3 and %4 are evaluated immediately, that is, during parsing - they are replaced by x and y respectively;

  • the command becomes: SET output=!output:x=y! ;

  • the team is about to execute - expression ! evaluated ( x is replaced by y s);

  • the command is executed - the variable output is changed.

Now for the warnings. The first thing to remember is that ! becomes part of the syntax and is consumed and interpreted whenever it occurs. Therefore, you will need to avoid this when you want to use it as a literal (e.g. ^! ).

Another caveat is the main effect of the SETLOCAL / ENDLOCAL block. The fact is that all changes in the environment variables inside such a block are, well, local. After exiting the block (after executing ENDLOCAL ), the variable is set to the value that was before it was entered (before SETLOCAL executed). This means that the changed output value will only be valid in the SETLOCAL block that you had to initiate in order to use delayed expansion in the first place. This may not be a problem in your particular case if you just need to change the value and then use it right away, but you may have to remember it in the future.

Note. According to jeb's comment, you can save the changed value and leave the SETLOCAL block with this trick:

 ENDLOCAL & SET "output=%output%" 

The & operator simply restricts the commands when they fit on the same line. They are executed one after another, in the same order they are indicated. The fact is that by the time the line was parsed, the SETLOCAL block has not yet been left, so %output% evaluates the modified value, which remains valid. But the assignment is really performed after ENDLOCAL , that is, after exiting the block. Thus, you effectively save the changed value after exiting the block, thereby saving the changes. (Thanks jeb !)




Additional Information:

+45
Apr 28 2018-11-11T00:
source share

I tried under the code in a Windows 7 batch file:

 SET output=%1 CALL SET output=%output:unsigned=signed% CALL SET output=%output:.apk=-aligned.apk% 

It works!

+3
Nov 21 '14 at 4:21
source share

If you need to substitute several parameters in one line, just use "for / f" to set the variable with the previous replacement as follows:

 SET "output1=%1" CALL SET output1=%%output1:%3=%4%% for /f "tokens=1" %%a in ('echo %output1%') do set output2=%%a CALL SET output2=%%output2:%5%6% for /f "tokens=1" %%a in ('echo %output2') do set output3=%%a 
0
Jan 29 '14 at 21:08
source share



All Articles