2

I have a script that reads thru file and sets variable as it finds it.

@echo off
Setlocal EnableDelayedExpansion

for /f "tokens=*" %%V in ('findstr /I /C:title= "%~1"') do set title=%%V
echo %title%

In the txt file there is "title=variable & speed". And the script only returns:

title=variable
'SPEED' is not recognized as an internal or external command,
operable program or batch file. 

As it should return whole line. This is the part, I have not found the solution yet. It should change the "&" to "-", as in finally this script renames files.

Joakim
  • 113
  • 7

2 Answers2

2

First, don't enable delayed expansion because of not needed here. It can result in findstr does not find the file to open if the batch file is called with a file name without or with a path containing one or more exclamation marks.

Second, the FOR option "tokens=*" results in removing leading spaces/tabs from a line output by FINDSTR not starting with a semicolon and if there is something left assign the rest of the line to specified loop variable. This is okay if this behavior is wanted here. Otherwise it would be better to use "delims=" which defines an empty list of delimiters resulting in assigning the entire line not starting with a semicolon to the specified loop variable. Not double quoted argument string delims^=^ eol^= defines an empty list of delimiters and no end of line character to get assigned also a line starting with a semicolon to the loop variable. The two equal signs and the space character must be escaped with caret character ^ to be interpreted as literal characters and not as argument separators.

Third, an ampersand outside a double quoted argument string is interpreted as operator to unconditionally execute the command after & after executing the command before &. For details see Single line with multiple commands using Windows batch file. For that reason it is recommended to enclose the argument string of command SET in double quotes as explained in detail on answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line?

So I suggest using following code:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "LoadedTitle="
for /F "tokens=*" %%V in ('%SystemRoot%\System32\findstr.exe /I /C:"title=" "%~1" 2^>nul') do set "LoadedTitle=%%V"
if defined LoadedTitle (
    setlocal EnableDelayedExpansion
    echo !LoadedTitle!
    endlocal
)
endlocal

Read this answer for details about the commands SETLOCAL and ENDLOCAL.

Please note that /C:"title=" is used instead of /C:title= on FINDSTR command line as otherwise FINDSTR would in this special case search just for title. The reason is that the command line within the round brackets is executed in a separate command process started by FOR with cmd.exe /C in background and the equal sign not enclosed in a double quoted string and not escaped with ^ would be removed by current command process because of being interpreted as separator. In a command prompt window it is possible to use the FINDSTR command line with /C:title= without double quotes, but not here on this FOR command line in batch file.

Read also the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded findstr command line with using a separate command process started in background.

Temporary enabling delayed expansion just for output of the line with loaded title string is required because of usage of only echo %LoadedTitle% would be modified before execution to echo title=variable & speed and the ampersand is again not interpreted as literal character to output by ECHO, but as operator to run speed after execution of echo title=variable .

I recommend to read

A batch file writer must always take into account what is finally executed by Windows command processor after parsing a command line one or more times as this can be different than what is written in batch file on using environment variable references with syntax %variable%.

Mofi
  • 46,139
  • 17
  • 80
  • 143
1

I Found the correct "formula" to script

@echo off
setlocal EnableExtensions EnableDelayedExpansion


for /F "tokens=*" %%V in ('%SystemRoot%\System32\findstr.exe /I /C:"title=" "%~1" 

2^>nul') do set "title=%%V"

set title=!title:^&=-!
    echo "!title!"
endlocal

As it does now that what I wanted, it returns:

"title=variable - SPEED"

It is not as you suggested but it does the job.

Joakim
  • 113
  • 7
  • I see you chose to ignore my comment above. You don't need to escape the ampersand if you quote the set statement. – Squashman Sep 27 '18 at 22:33