0

i am trying to code a simple script in batch that can find and replace a line

so far, I've found a snippet that works perfectly fine for my purpose the only problem is that it removes empty lines and i can't figure out why!!

I've tried to add another if statement in this for loop but I fail also I found that there is a bat called JREPL, i tried to run few simple commands from the docs and i failed again XD

here is the snippet:

:Variables
set InputFile=t.txt
set OutputFile=t-new.txt
set _strFind= old "data"
set _strInsert= new "data";

:Replace
>"%OutputFile%" (
  for /f "usebackq delims=" %%A in ("%InputFile%") do (
    if "%%A" equ "%_strFind%" (echo %_strInsert%) else (echo %%A)
  )
)

i was expecting that this snippet won't remove my empty lines and i can't figure out why

dbenham
  • 127,446
  • 28
  • 251
  • 390
abdelhamied mostafa
  • 215
  • 1
  • 3
  • 14

2 Answers2

2

I am posting this without testing, as I do not have the environment to test as we speak. But to explain your issue, cmd will ommit empty lines as it is built that way. It is the same as setting a variable to nothing and expecting it to return a result, so we simply assign values to each line by sort of simulating a detection of line breaks (Don't know exactly how to explain that one) but nevertheless, we will add some additional characters to the lines to ensure we get line breaks, the just get rid of them once we have them, So here goes:

@echo off
setlocal enabledelayedexpansion

set inputfile=t.txt
set outputfile=t-new.txt
set _strfind=old "data"
set _strinsert=new "data";
for /f "tokens=*" %%a in ('type "%inputfile%" ^| find /v /n "" ^& break ^> "%inputfile%"') do (
    set "str=%%a"
    set "str=!str:*]=!"
    if "!str!"=="%_strfind%" set "str=%_strinsert%"
    >>%outputfile% echo(!str!
)

That should send to output file.. You can however make the output file the same as the input as it would then be the same as replacing the text inline in the original file. Once I am able to test, I will fix the answer if there are any issues with it.

As a side note, be careful of where you have additional whitespace in your variables you set. For instance:

set a = b

has 2 issues, the variable, containing a space after a will be created with the space. So it will be seen as:

%a %

The aftermath of this is that the value of the variable will start with a leading space, so when you expected b as the value, it in fact became b

Then lastly, it is alsways a good idea to enclose your variables with double quotes, simply again to eliminate whitespace, because:

 set a=b 

Even though you cannot see it with your naked eyes, contains a space at the end, so doing a direct match like:

if "b"=="b"

Will result in a false statement as in fact we have:

if "b"=="b "

So the correct statement would be to set variables as:

set "a=b"
if "%a%"=="b"

which will be a perfect match.

Note I posted this from my phone, so any spelling, grammar and code issues I will resolved as I go though my answer.

Gerhard
  • 22,678
  • 7
  • 27
  • 43
  • thanks that worked.. i have a question if the line i tend to replace was something like this >> import "file.txt" << is it possible to replace it? – abdelhamied mostafa Jan 14 '19 at 21:12
  • nevermind, I get what you mean, I see it in your question, let me update my answer. – Gerhard Jan 14 '19 at 21:15
  • i've this text in the file
    import "hello.txt" . . . some other stuff

    i want to replace import statement to import "hi.txt"
    – abdelhamied mostafa Jan 14 '19 at 21:17
  • The only thing I don't like here is the fact that the output file becomes opened and closed for every single line, opposed to the OP's code, which opens and closes it exactly once... – aschipfl Jan 15 '19 at 09:19
  • 1
    @aschipfl, I am not going to lie to you, but I know I had an issue with the single open when writing back to the origial file, but I cannot recall what the issue was, that is why. So yes, as OP is writing to another output file, that would be better, but I left this as is because of my forgotton reason... When I have time I will test again and see if I can recall the issue I had. – Gerhard Jan 15 '19 at 09:22
1

…and one way using JREPL

JRepl "old \qdata\q" "new \qdata\q;" /I /XSEQ /F "t.txt" /O "t-new.txt"
Compo
  • 36,585
  • 5
  • 27
  • 39
  • can you explain more what each parameter does – abdelhamied mostafa Jan 14 '19 at 21:38
  • I've never used `JRepl`, you stated that you'd tried some commands from the docs so I simply took a 1 minute look at the usage information and threw it together. I would have considered helping more but not after you've already accepted someone else's answer. The author has provided over 1200 lines of comment/usage information, you should read it yourself. – Compo Jan 14 '19 at 21:51
  • \q for double quotes? what is for single quote – abdelhamied mostafa Jan 14 '19 at 22:19
  • I repeat, the author has provided over 1200 lines of comment/usage information, you should read it yourself. – Compo Jan 14 '19 at 22:45
  • @abdelhamiedmostafa - single quotes don't need an escape sequence. Double quotes need an escape sequence because the CSCRIPT Windows script host that JREPL relies on does not support `"` literals within parameters. – dbenham Mar 11 '20 at 21:37