I'm new to the batch editing in Windows, and I'm getting very confused by the impossibility to use PowerShell commands inside my bat file.
Long story short I have this input file:
The quick brown fox jumped over the lazy white dog
The quick red fox jumped over the lazy dog
The quick green wolf jumped over the lazy brown dog
The quick brown fox jumped over the lazy dog
The quick red lion jumped over the lazy dog
The quick green pig jumped over the lazy brown dog
The quick brown fox jumped over the lazy dog
I would like to substitute brown
with white
, if the sentence is containing the term fox
.
As an extra requirement, I would like to replace brown
only if it's the first occurrence.
I tried to work with .contains
and with find
, but still it all get's messy when I try to use the outcome of the if
condition.
The best I managed to put together was this; but it's still crap.
@echo on &setlocal
set "search=brown"
set "replace=white"
set "textfile=C:\JavaLogs\ReplaceDemo.txt"
set "newfile=C:\JavaLogs\Output.txt"
set lines=0
(
for /f "delims=" %%i in (%textfile%) do (
set lines=echo %%i | findstr /C:"fox" | measure -w -c -l
echo %lines%
if "%lines%">"0" echo "There is a fox"
if "%lines%"=="0" echo "There is no fox"
set %%i=%%i:%search%=%replace% echo(%%i>%newfile%)
else echo(!%%i!)>"%newfile%"
)
)
The final resut would be an output file like this:
The quick white fox jumped over the lazy white dog
The quick red fox jumped over the lazy dog
The quick green wolf jumped over the lazy brown dog
The quick white fox jumped over the lazy dog
The quick red lion jumped over the lazy dog
The quick green pig jumped over the lazy brown dog
The quick white fox jumped over the lazy dog
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the directories and filenames are names
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
SET "filename1=%sourcedir%\q77026292.txt"
SET "outfile=%destdir%\outfile.txt"
SET "prerequisite=fox"
SET "replace=brown"
SET "replacement=white"
(
FOR /f "usebackqdelims=" %%e IN ("%filename1%") DO (
rem line is in %%e
SET "foundpre="
FOR %%o IN (%%e) DO IF "%%o"=="%prerequisite%" SET "foundpre=y"
IF DEFINED foundpre (
SET "outline="
SET "replace1=y"
FOR %%o IN (%%e) DO IF DEFINED replace1 (
IF "%%o"=="%replace%" (
SET "replace1="
SET "outline=!outline! %replacement%"
) ELSE SET "outline=!outline! %%o"
) ELSE SET "outline=!outline! %%o"
ECHO !outline:~1!
) ELSE ECHO %%e
)
)>"%outfile%"
GOTO :EOF
Note that if the filename does not contain separators like spaces, then both usebackq
and the quotes around %filename1%
can be omitted.
Note the use of delayedexpansion
Stephan's DELAYEDEXPANSION link as the value of outline
is changing in the for %%e
loop, and of Boolean variables which are interpreted on their run-time state.
Revision in the light of comments ----
@ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the directories and filenames are names
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
SET "filename1=%sourcedir%\q77026292.txt"
SET "outfile=%destdir%\outfile.txt"
SET "prerequisite=fox"
SET "replace=brown"
SET "replacement=white"
(
FOR /f "usebackqdelims=" %%e IN ("%filename1%") DO (
rem line is in %%e
SET "foundpre="
SET "line=%%e"
SET "line=!line:|=" "!"
FOR %%o IN ("!line!") DO IF "%%~o"=="%prerequisite%" SET "foundpre=y"
IF DEFINED foundpre (
SET "outline="
SET "replace1=y"
FOR %%o IN ("!line!") DO IF DEFINED replace1 (
IF "%%~o"=="%replace%" (
SET "replace1="
SET "outline=!outline! "%replacement%""
) ELSE SET "outline=!outline! %%o"
) ELSE SET "outline=!outline! %%o"
SET "outline=!outline:~2,-1!"
ECHO !outline:" "=^|!
) ELSE ECHO %%e
)
)>"%outfile%"
TYPE "%outfile%"
GOTO :EOF
The original code used the characteristic of the for
command that it assigns each of the space-separated items in the list in turn to the metavariable.
With |
as the item-separator, we need to massage the line a little.
line
would be initially set to (eg)
The quick|brown|fox|jumped|over|the|lazy|brown|unicorn
so the SET "line=!line:|=" "!"
changes replaces each |
with " "
, so changes this to
The quick" "brown" "fox" "jumped" "over" "the" "lazy" "brown" "unicorn
and then FOR %%o IN ("!line!")...
processes
"The quick" "brown" "fox" "jumped" "over" "the" "lazy" "brown" "unicorn"
and assigns each quoted substring in turn to %%o
.
It's then a matter of replacing %%o
with %%~o
to strip the enclosing quotes from %%o
when appropriate. (Yes - "%%~o"
is the same as %%o
if we know (as we do here) that %%o
is quoted)
and then reversing the transformation to replace " "
with |
- the |
needs to be escaped with ^
here.