I'm trying to set a variable (Let's say, filehash is the variable name) from a file using batch file. Alas, I was stuck facing these two problems:
When it contains special characters, especially exclamation mark(s) as I'm using enableDelayedExpansion.
While doing that, I need to change &
to & as well.
I've tried several solutions provided from various sources but none would fit my requirements.
Here's my current code:
@echo off
set grep=binaries\grep.exe
set fileindex=binaries\index.htm
set count=0
for /f "tokens=* delims=" %%a in (crc.dat) do (
set count=!count! + 1
set filehash=%%a
%grep% --ignore-case -w "!filehash!" %fileindex%>> list.dat
)
And an example of what's inside the crc.dat file:
Kabooom! Kablooey!
Kaboom & Kablooey
And the result using my current code above in list.dat:
Kabooom Kablooey
Kaboom & Kablooey
The result that I'm expecting in list.dat:
Kabooom! Kablooey!
Kaboom & Kablooey
I hope I conveyed my problem properly and thank you in advance!
To replace &
by &
in the input of grep
, use this:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "grep=binaries\grep.exe"
set "fileindex=binaries\index.htm"
set "file=crc.dat"
set "list=list.dat"
rem // Initialise counter:
set /A "count=0"
> "%list%" (
for /F "usebackq delims=" %%a in ("%file%") do (
rem // Increment counter:
set /A "count+=1"
rem // Assign line string to variable:
set "lineitem=%%a"
rem // Toggle delayed expansion:
setlocal EnableDelayedExpansion
rem // Do sub-string replacement:
set "lineitem=!lineitem:&=&!"
rem // Execute `grep` command line:
"!grep!" --ignore-case -w "!lineitem!" "!fileindex!"
endlocal
)
)
rem // Return counter:
echo/%count%
endlocal
To replace &
by &
in the output of grep
, use this:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "grep=binaries\grep.exe"
set "fileindex=binaries\index.htm"
set "file=crc.dat"
set "list=list.dat"
rem // Initialise counter:
set /A "count=0"
> "%list%" (
for /F "usebackq delims=" %%a in ("%file%") do (
rem // Increment counter:
set /A "count+=1"
rem // Execute `grep` command line and capture its output by `for /F`:
for /F "delims=" %%b in ('^""%grep%" --ignore-case -w "%%a" "%fileindex%"^"') do (
rem // Assign `grep` output to variable:
set "lineitem=%%b"
rem // Toggle delayed expansion:
setlocal EnableDelayedExpansion
rem // Do sub-string replacement:
set "lineitem=!lineitem:&=&!"
rem // Return modified string:
echo(!lineitem!
endlocal
)
)
)
rem // Return counter:
echo/%count%
endlocal
In general, to handle strings with exclamation marks, you must toggle delayed expansion, so that normal %
-expanded variables and for
variable references like %%a
become expanded with delayed expansion disabled.
This is a solution which is delayedExpansion
-free and able to replace &
to &
.
@echo off
set grep=binaries\grep.exe
set fileindex=binaries\index.htm
set count=0
for /f "tokens=* delims=" %%a in (crc.dat) do (
set /a count+=1
%grep% --ignore-case -w "%%a" %fileindex%>>temp.dat
)
powershell -Command "(gc temp.dat) -replace '&', '&' | sc list.dat"
del /f temp.dat
pause
exit /b
Some changed things:
set /a count+=1
= set /a count=%count%+1
!fileHash!
points to %%a
, so why do we need it? %%a
will work. powershell
command replaces &
with &
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.