Conditionally replace slash with jrepl.bat

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
paolo2504
Posts: 18
Joined: 27 Jan 2022 11:23

Conditionally replace slash with jrepl.bat

#1 Post by paolo2504 » 27 Feb 2022 17:21

With jrepl.bat i am trying to do as follow.
I need to change all slash to backslash in every lines in a .ini text file only when some conditions are met.
example

key0=http://www.websiteinfo.com/somepage/someindex.html
key1=image/a0/a123.wav
key2=images/a0/a1234.wav
key3=./images/a0/a1234.wav
key4=new value 2 / 3.1
key5=new value 2 / 63.3
key6=new value 3 / 3.3 / xxxx

key0,1,2,3 every slash must be replaced with basckslah
key4,5,6 no change must be done
Generally speaking, lines to be changed may end (or start) in some way that i can identify. In the examples above, lines to be changed end with ".wav" but how tell jrepl to replace / with \ ONLY when it finds ".wav" at the end of lines that contain "/" ??
any hint applreciated.

Aacini
Expert
Posts: 1885
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Conditionally replace slash with jrepl.bat

#2 Post by Aacini » 27 Feb 2022 20:32

It has to be using JRepl? This pure Batch file do it:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

set "changeExt=.html.wav"

for /F "delims=" %%a in (test.ini) do (
   set "line=%%a"
   if "!changeExt:%%~Xa=!" neq "%changeExt%" (
      set "line=!line:/=\!"
   )
   echo !line!
)
Output:

Code: Select all

key0=http:\\www.websiteinfo.com\somepage\someindex.html
key1=image\a0\a123.wav
key2=images\a0\a1234.wav
key3=.\images\a0\a1234.wav
key4=new value 2 / 3.1
key5=new value 2 / 63.3
key6=new value 3 \ 3.3 \ xxxx
Antonio

paolo2504
Posts: 18
Joined: 27 Jan 2022 11:23

Re: Conditionally replace slash with jrepl.bat

#3 Post by paolo2504 » 28 Feb 2022 01:59

Thanks aAcini for reply.
Yes, I use jrepl because it is much faster than any piece of code I wrote.

Anyway, I should explain better.

Actually, I have to replace multi strings in a file: let’s say 2-3 strings for every line and a fourth one only if line itself ends with (just an example) .wav

With jrepl multi replacement is easy. Something like this:
%findstr%=“.\|\\|\image”
%replstr%=“””|””|image”
| is the separator.
(In this example “.\” and “\\” are removed while “\image” is changed to “image”. All done with just one call to jrepl.

Problem is that I must also change “/“ to “\” but only for lines that end with .wav.
I cannot set findstr= “.\|\\|\image|/“ and
replstr= “””|””|image|\” because this would replace every slash.

It seems I have to call jrepl two times, that is something I don’t want to do.

paolo2504
Posts: 18
Joined: 27 Jan 2022 11:23

Re: Conditionally replace slash with jrepl.bat

#4 Post by paolo2504 » 28 Feb 2022 03:54

I tried anyway the code you so gently posted here and it doesnt work (it doesnt read lines and %%a contains the filename).
This ways it does; however, as said before, it is very very slow compared with jrepl.

@echo off
setlocal EnableDelayedExpansion
set changeExt=".png"
for /f "usebackq tokens=*" %%a in ("oldfile.ini") do (
set line=%%a
if "!line:%changeExt%=!" neq "%line%" (
set line=!line:/=\!
echo !line!>>d:\newfile.ini
)
)
endlocal
exit /b

Aacini
Expert
Posts: 1885
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Conditionally replace slash with jrepl.bat

#5 Post by Aacini » 28 Feb 2022 16:33

The problem is that the regex methods usually replace substrings in the whole file. In your case, you need to process the file line-by-line to test for the condition (include .html or .wav) and then do the replace...

However, you don't need a program as large as jrepl.bat (or my own FindRepl.bat for that matter) in order to achieve this replacement. The Batch-JScript hybrid file below do what you want:

Code: Select all

@set @a=0  // & cscript //nologo //E:JScript "%~F0" < input.txt & goto :EOF

// Read all file contents
var Contents = WScript.StdIn.ReadAll();

// First pass: replace substrings in *all* file contents
var repl = new Array();
repl[".\\"] = "";
repl["\\\\"] = "";
repl["\\image"] = "image";
Contents = Contents.replace(/\.\\|\\\\|\\image/g, function (A) {return repl[A]});

// Second pass: replace substrings in line-by-line basis
var lines = Contents.split("\r\n");
for ( var i = 0; i < lines.length; i++ ) {
   var line = lines[i];
   if ( line.search(/\.html|\.wav/i) >= 0 ) {
      line = line.replace(/\//g,"\\");
   }
   WScript.Stdout.WriteLine(line);
}
An additional problem in your case is that the the backslash must be preceded by an additional backslash always, and the point must be preceded by a backslash when it is used in a regex.

I used this file as input:

Code: Select all

key0=http://www.websiteinfo.com/somepage/someindex.html
key1=image/a0/a123.wav
key2=images/a0/a1234.wav
key3=./images/a0/a1234.wav
key4=new value 2 / 3.1
key5=new value 2 / 63.3
key6=new value 3 / 3.3 / xxxx
key7=HERE.\THERE\\AND\imageEVERYWHERE
And this is the output:

Code: Select all

key0=http:\\www.websiteinfo.com\somepage\someindex.html
key1=image\a0\a123.wav
key2=images\a0\a1234.wav
key3=.\images\a0\a1234.wav
key4=new value 2 / 3.1
key5=new value 2 / 63.3
key6=new value 3 / 3.3 / xxxx
key7=HERETHEREANDimageEVERYWHERE
Antonio

paolo2504
Posts: 18
Joined: 27 Jan 2022 11:23

Re: Conditionally replace slash with jrepl.bat

#6 Post by paolo2504 » 01 Mar 2022 11:53

i do appreciate your support.
just a couple of questions:
your code writes changes to stdout (screen). How to write changes to the input file (or to a new file) ?
note: i tried this @set @a=0 // & cscript //nologo //E:JScript "%~F0" < d:\kalvtrask.organ > d:\kalvtrasknew.txt & goto :EOF
it works and also hide cript execution. Is this method ok ? If yes, is it possible to directly update the original file somehow ? or have i to write new file, delete old one and rename new to old (or, more directly, create new file then move it to the old ?).

How echo off output ?

I don’t understand function(A): where “A” is defined ?

Is it possible to insert such hybrid jscript code in a batch file as a function ? I mean:
REM Batch start
Here code
Here code
……..
Call :hybrid-function-replace
Here code again
…..
….
REM batch end
Exit /b

i keep in mind your piece of code for the future.
thanks very much.

paolo2504
Posts: 18
Joined: 27 Jan 2022 11:23

Re: Conditionally replace slash with jrepl.bat

#7 Post by paolo2504 » 08 Mar 2022 12:47

Aacini wrote:
28 Feb 2022 16:33

hi Aacini,
i need your kind help. I am trying to use your code to avoid calling jrepl.bat.
Your code works but now i need to do the string replacements using variable strings passed from the batch portion.
The code below is your code modified. I see parameters are passed to the jscript portion but the search is not working and so the replace is not made.
var Findchr is correctly populated, no error arises but replace is not made.
I tried to .split Finchr to create an array but this also doesnt work.
Pls a little help needed...


Note: this is a portion of the main batch file. The batch code with the csript command belongs to a called function

@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment
@echo off

rem we are inside a called function...
rem qui le variabili
set Infile="D:\beiaard\Beiaard_3.organ"
set Outfile="D:\beiaard\Beiaard_3.organ.new"
set findchr="\.\\|\.\/|\\\\|image=\\"
set replchr="""|""|""|image="

rem here starts a for /f loop on all .organ text files in a folder
cscript //nologo //E:JScript "%~F0" < %Infile% > %Outfile% %findchr% %replchr%
rem move /y Outfile Infile>nul
goto :EOF

************* JScript portion **********/
// Read all file contents
args = WScript.Arguments;
Findchr=args(0);
Replchr=args(1);


// log_start
var ForReading = 1, ForWriting = 2, ForAppending = 8;
var fso = new ActiveXObject("Scripting.FileSystemObject");
// Open the file for output.
var filename = "d:\\jslog.txt";
var f = fso.OpenTextFile(filename, ForWriting, true);
// Write to the file.
f.WriteLine("Findchr = " + Findchr);
f.WriteLine("Replchr = " + Replchr);
f.Close();
// log_end


var Contents = WScript.StdIn.ReadAll();

// First pass: replace substrings in *all* file contents
var repl = new Array();
repl["\.\\"] = "";
repl["\.\/"] = "";
repl["\\\\"] = "";
repl["image=\\"] = "image=";
repl["Per Zacharias Strand\\"] = ""

// also trying to build array from string with .split does not work
// var FindArray=new Array();
// var ReplArray=new Array();
// var FindArray = Findchr.split("|");
// var ReplArray = Replchr.split("|");

// this works but i need to use Findchr (= strings from batch) not fixed strings inside jscript...
Contents = Contents.replace(/\.\\|\.\/|\\\\|image=\\|Per Zacharias Strand\\/gi, function (A) {return repl[A]});

// this does not work strings not replaced
// Contents = Contents.replace(/Findchr/gi, function (A) {return repl[A]});

// Second pass: replace substrings in line-by-line basis
var lines = Contents.split("\r\n");
for ( var i = 0; i < lines.length; i++ ) {
var line = lines;
if ( line.search(/\.png|\.jpg/i) >= 0 ) {
line = line.replace(/\//g,"\\");
}
WScript.Stdout.WriteLine(line);
}

paolo2504
Posts: 18
Joined: 27 Jan 2022 11:23

Re: Conditionally replace slash with jrepl.bat

#8 Post by paolo2504 » 08 Mar 2022 16:41

paolo2504 wrote:
08 Mar 2022 12:47
Aacini wrote:
28 Feb 2022 16:33

hi Aacini,
i need your kind help. I am trying to use your code to avoid calling jrepl.bat.
Your code works but now i need to do the string replacements using variable strings passed from the batch portion.
The code below is your code modified. I see parameters are passed to the jscript portion but the search is not working and so the replace is not made.
var Findchr is correctly populated, no error arises but replace is not made.
I tried to .split Finchr to create an array but this also doesnt work.
Pls a little help needed...


Note: this is a portion of the main batch file. The batch code with the csript command belongs to a called function

@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment
@echo off

rem we are inside a called function...
rem
set Infile="D:\beiaard\Beiaard_3.organ"
set Outfile="D:\beiaard\Beiaard_3.organ.new"
set findchr="\.\\|\.\/|\\\\|image=\\"
set replchr="""|""|""|image="

rem here starts a for /f loop on all .organ text files in a folder ………
cscript //nologo //E:JScript "%~F0" < %Infile% > %Outfile% %findchr% %replchr%
rem move /y Outfile Infile>nul
goto :EOF

************* JScript portion **********/
// Read all file contents
args = WScript.Arguments;
Findchr=args(0);
Replchr=args(1);


// log_start
var ForReading = 1, ForWriting = 2, ForAppending = 8;
var fso = new ActiveXObject("Scripting.FileSystemObject");
// Open the file for output.
var filename = "d:\\jslog.txt";
var f = fso.OpenTextFile(filename, ForWriting, true);
// Write to the file.
f.WriteLine("Findchr = " + Findchr);
f.WriteLine("Replchr = " + Replchr);
f.Close();
// log_end


var Contents = WScript.StdIn.ReadAll();

// First pass: replace substrings in *all* file contents
var repl = new Array();
repl["\.\\"] = "";
repl["\.\/"] = "";
repl["\\\\"] = "";
repl["image=\\"] = "image=";
repl["Per Zacharias Strand\\"] = ""

// also trying to build array from string with .split does not work
// var FindArray=new Array();
// var ReplArray=new Array();
// var FindArray = Findchr.split("|");
// var ReplArray = Replchr.split("|");

// this works but i need to use Findchr (= strings from batch) not fixed strings inside jscript...
Contents = Contents.replace(/\.\\|\.\/|\\\\|image=\\|Per Zacharias Strand\\/gi, function (A) {return repl[A]});

// this does not work strings not replaced
// Contents = Contents.replace(/Findchr/gi, function (A) {return repl[A]});

// it could be also acceptable not to pass variables
// however I could have many repl[…] items…
// how declare all “repl” items and use a single cumulative or array var in the search ?


// Second pass: replace substrings in line-by-line basis
var lines = Contents.split("\r\n");
for ( var i = 0; i < lines.length; i++ ) {
var line = lines;
if ( line.search(/\.png|\.jpg/i) >= 0 ) {
line = line.replace(/\//g,"\\");
}
WScript.Stdout.WriteLine(line);
}

Aacini
Expert
Posts: 1885
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Conditionally replace slash with jrepl.bat

#9 Post by Aacini » 09 Mar 2022 14:01

Mmm... A couple points about your request...

In first place, you should read the first post of this forum. You should state the requirements in a very clear way. You should explain what you want to do: why you want the replacements be done via Batch variables? Show us a couple examples of such variable replacements. (If you show us the same example of the previous constant replacement, my answer would be: "You don't need variable replacements". Isn't it?)

You should pay attention to the format of your posts. Currently, it seems that your new code is a quoted citation from a previous reply of my own. Be careful where you place the [quote]...[/quote] tags (or even if you need such tags!), and enclose your code between [code]...[/code] tags! Use the Preview button and review your reply before post it...

The creation of output files is achieved via > outputFile.txt Batch redirection. This avoids the open/write/close file JScript statements (unless you want to make your code unnecessarily complicated).

You have not mentioned the creation of d:\\jslog.txt file before

Anyway, this is a new attempt to give you an answer to your request:

Code: Select all

@if (@CodeSection == @Batch) @then

@echo off
setlocal

rem  This is a "more standard" way to write a Batch-JScript hybrid script
rem  You may place any Batch code here
rem  the Batch code ends at "at-sign end" line below

rem Define replacement variables
set findchr="\.\\|\.\/|\\\\|image=\\"
set replchr="|||image="
set extchr="\.html|\.wav"

rem Here starts a loop over all "test*.txt" files in *current* folder
for %%f in (test*.txt) do (
   echo Processing: "%%f"
   rem This is the call to the "replacement subroutine"
   cscript //nologo //E:JScript "%~F0" %findchr% %replchr% %extchr%  <"%%f" >"%%f.new" 2>jslog.txt
   rem Move new file to the old one
   move /Y "%%f.new" "%%f"  > NUL
)
goto :EOF


@end


// Create replacement array for Contents.replace() method
var args = WScript.Arguments,
    Findchr = args.Item(0),               // Findchr = "\.\\|\.\/|\\\\|image=\\";
    Replchr = args.Item(1),               // Replchr = "|||image="
    FindArray = Findchr.split("|"),       // FindArray[0]="\.\\"; FindArray[1]="\.\/"; ...
    ReplArray = Replchr.split("|"),       // ReplArray[0]=""; ... ReplArray[3]="image=";
    regexFile = eval("/"+Findchr+"/gi"),  // same as regexFile = /\.\\|\.\/|\\\\|image=\\/gi;
    regexExt  = new RegExp(args.Item(2),"gi"),    // another way to do the same
    repl = new Array();

for ( var i = 0; i < FindArray.length; i++ ) {
   repl[FindArray[i]] = ReplArray[i];  // repl["\.\\"]=""; ... repl["image=\\"]="image=";

   // Delete next line...
   WScript.Stderr.WriteLine("["+i+"]: '"+FindArray[i] + "' = '" + repl[FindArray[i]]+"'");

}

// Log
WScript.Stderr.WriteLine("Findchr = " + Findchr);
WScript.Stderr.WriteLine("Replchr = " + Replchr);

// Read all file contents
var Contents = WScript.StdIn.ReadAll();

// First pass: replace substrings in *all* file contents
Contents = Contents.replace(regexFile, function (A) {return repl[A]});

// Second pass: replace substrings in line-by-line basis
var lines = Contents.split("\r\n");
for ( var i = 0; i < lines.length; i++ ) {
   var line = lines[i];
   if ( line.search(regexExt) >= 0 ) {
      line = line.replace(/\//g,"\\");
   }
   WScript.Stdout.WriteLine(line);
}
IMPORTANT: For a reason I can't fathom out, the replacement of image=\\ fails! If the string not ends in double backslash, the replacement works OK. Perhaps someone here could help us in this sole point...

Input example:

Code: Select all

key0=http://www.websiteinfo.com/somepage/someindex.html
key1=\\image/a0/a123.wav
key2=.\images/a0/a1234.wav
key3=./images/a0/a1234.wav
key4=new value 2 / 3.1
key5=new value 2 / 63.3
key6=new value 3 / 3.3 / xxxx
image=\file\name.ext
Output:

Code: Select all

key0=http:\\www.websiteinfo.com\somepage\someindex.html
key1=image\a0\a123.wav
key2=images\a0\a1234.wav
key3=images\a0\a1234.wav
key4=new value 2 / 3.1
key5=new value 2 / 63.3
key6=new value 3 / 3.3 / xxxx
file\name.ext
Antonio

PS - Please, read the first post in this forum...

paolo2504
Posts: 18
Joined: 27 Jan 2022 11:23

Re: Conditionally replace slash with jrepl.bat

#10 Post by paolo2504 » 10 Mar 2022 14:45

Antonio,
foa i do appreciate your help. I also understand your words about reading first post (done!) and what to do writing post. I'll try to do my best.
First of all a quick explanation of what i'm doing.
A free Organ virtual simulator named GrandOrgue is able to use samplesets of real organs around the world. The configuration file is text file with section, keys and values; basically a .ini file.
Samplesets are often created in linux systems and contain characters somehow not compatible in Windows: think to paths for example (./xxx/yyy/... that in Windows must be \xxx\yyy\...).
I wrote a batch that makes lot of things (not necessary to explain now); one of the function is called to 'clean' the sampleset configuration file and convert it to a format readable in Windows 10.
That's all. With jrepl i do the 95% of the job in a quick way. I was trying to optimize code when i read your post: you gave the idea to insert jscript code ... and so here we are...
Here below a test configuration file (build from real one for testing) and my last code. I fully reviewed code even before your last post. It works, basically it's quite similar to yours. There is only a problem with object.keys: i can't use this method because i get error property or method not supported so i use the standard way (but i would prefer to use, if possible, the one with objectkeys.
PS. solved issue with Image=...

best regards.
Attachments
jsrepl_ok.zip
(854 Bytes) Downloaded 262 times
beiaard.zip
(1.36 KiB) Downloaded 271 times

paolo2504
Posts: 18
Joined: 27 Jan 2022 11:23

Re: Conditionally replace slash with jrepl.bat

#11 Post by paolo2504 » 10 Mar 2022 16:30

paolo2504 wrote:
10 Mar 2022 14:45
Antonio,
foa i do appreciate your help. I also understand your words about reading first post (done!) and what to do writing post. I'll try to do my best.
First of all a quick explanation of what i'm doing.
A free Organ virtual simulator named GrandOrgue is able to use samplesets of real organs around the world. The configuration file is text file with section, keys and values; basically a .ini file.
Samplesets are often created in linux systems and contain characters somehow not compatible in Windows: think to paths for example (./xxx/yyy/... that in Windows must be \xxx\yyy\...).
I wrote a batch that makes lot of things (not necessary to explain now); one of the function is called to 'clean' the sampleset configuration file and convert it to a format readable in Windows 10.
That's all. With jrepl i do the 95% of the job in a quick way. I was trying to optimize code when i read your post: you gave the idea to insert jscript code ... and so here we are...
Here below a test configuration file (build from real one for testing), itself replaced and my last code. I fully reviewed code even before your last post. It works, basically it's quite similar to yours. There is only a problem with object.keys: i can't use this method because i get error property or method not supported so i use the standard way (but i would prefer to use, if possible, the one with objectkeys.
PS. solved issue with Image=...

best regards.

ShadowThief
Expert
Posts: 1160
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Conditionally replace slash with jrepl.bat

#12 Post by ShadowThief » 10 Mar 2022 20:39

Quoting yourself isn't going to make us respond faster.

paolo2504
Posts: 18
Joined: 27 Jan 2022 11:23

Re: Conditionally replace slash with jrepl.bat

#13 Post by paolo2504 » 11 Mar 2022 02:38

Sorry it was an error. The intention was to re- edit my post, not to quote myself.

paolo2504
Posts: 18
Joined: 27 Jan 2022 11:23

Re: Conditionally replace slash with jrepl.bat

#14 Post by paolo2504 » 11 Mar 2022 12:45

I have been told that object.keys is not supported in ma/jscript. This explains why I am getting method / property error.

Il search some other solutions.

This said, I think this post can be closed.
Many thanks to AAcini.

Post Reply