1

I am trying to replace only the first match in a text file.

My code is:

FOR /R %%a IN ("*.out") DO call C:\qsi\jrepl.bat "FF**********" "**********" /f "%%a" /L /m /o -

The FF before the asterisks is representing a form feed character.
The code is for removing the form feed for the first match only.

I was trying to play with /p & /pflag "i", but could not get it to work.

I am using the latest version 8.2 of JREPL.BAT.

dbenham
  • 127,446
  • 28
  • 251
  • 390
  • if this is just one match in one text file, why are you automating it? are you trying to test for a bigger job, will the `FF` be re-added regularly, or what is your final output supposed to be? – mael' Jul 11 '19 at 14:22
  • the text files have more than one match but I only want the first match to be replaced then stop. These are PCL print files and I dont have access to the DLL source code to stop it from adding it in the first place when generating the print files. If the FF is there at the beggining of the file it prints a blank page and costs us clicks on our printers. If I remove the FF from the remaining matches then it messes up the printing. – Online Statements Jul 11 '19 at 14:33
  • What exactly have you tried with `/P`/`/PFLAG`? what about `/P "^.*$" /PFLAG ""` (just guessing...)? – aschipfl Jul 11 '19 at 15:29
  • what does "^.*$" do? I have tried FOR /R %%A IN ("*.out") DO call C:\qsi\jrepl.bat /p "\f*****" "*****" /l /xseq "(?:[^\n]*\n){1,10}" /PFLAG "" /f "%%A" /L /m /o - – Online Statements Jul 11 '19 at 16:06

1 Answers1

0

It is possible to use the JREPL.BAT option /INC if the first form feed is within a specific block at top of a text file and there is never one more form feed in same block.

Example for first form feed within the lines 3 to 10:

@echo off
for /R %%I in ("*.out") do call C:\qsi\jrepl.bat "\f" "" /INC "3:10" /F "%%I" /O -

The JScript regular expression search string \f matches a form feed control character.
The replace string is an empty string to remove the form feed in this include block.

The option /L for a literal search cannot be used on using \f or alternatively \x0C (hexadecimal value of form feed control character) in search string.

The option /M cannot be used on using option /INC as explained by help output on running JREPL.BAT in a command prompt window with /? or /??. The lines respectively the line endings must be detected and counted to identify the block from line 3 to line 10 on which the replace should be done and nothing outside this block.

A solution using option /PFLAG is also possible by using:

for /R %%I in ("*.out") do call C:\qsi\jrepl.bat "\f" "" /M /P "\f" /PFLAG "" /F "%%I" /O -

JREPL.BAT runs a JScript regular expression replace with these options searching for a form feed character in entire file because of option /M. It replaces only first form feed because of using the option /PFLAG "" which means running the case-sensitive replace without flag g for a non-global replace.

But it is necessary to specify also option /P with a regular expression string in addition to the regular expression search string specified as first argument for usage of option /PFLAG with empty flag string "" or with "i" for a non-global case-insensitive search. In this case the additional regular expression after /P is the same as the main search expression, just \f to match a form feed, the first form feed in entire file.


UPDATE:

The real task is to remove in a binary file first and only occurrence of the byte sequence 1B 45 and first occurrence of 0C being always after 1B 45 with keeping all other 0C in file. The binary file contains for example beginning at byte offset 752 (hexadecimal 02F0) the bytes:

02F0h: F8 00 FC 01 F8 00 0D 0A 0D 1B 45 1B 28 73 30 70 ; ø.ü.ø.....E.(s0p
0300h: 30 73 33 62 31 32 68 34 31 30 31 54 1B 26 6C 32 ; 0s3b12h4101T.&l2
0310h: 61 30 6F 30 65 30 6C 38 64 38 38 46 0D 0A 1B 2A ; a0o0e0l8d88F...*
0320h: 70 30 78 30 59 1B 2A 63 35 37 36 30 78 37 39 32 ; p0x0Y.*c5760x792
0330h: 30 59 1B 2A 63 30 54 1B 25 31 42 53 50 31 3B 53 ; 0Y.*c0T.%1BSP1;S
0340h: 43 30 2C 33 2E 33 38 36 37 2C 30 2C 2D 33 2E 33 ; C0,3.3867,0,-3.3
0350h: 38 36 37 2C 32 3B 49 52 30 2C 31 30 30 2C 30 2C ; 867,2;IR0,100,0,
0360h: 31 30 30 3B 53 50 31 3B 44 54 5E 2C 31 3B 53 44 ; 100;SP1;DT^,1;SD
0370h: 32 2C 31 2C 34 2C 31 30 2C 35 2C 30 2C 36 2C 33 ; 2,1,4,10,5,0,6,3
0380h: 2C 37 2C 34 31 34 38 3B 1B 25 31 41 0D 0A 0D 0A ; ,7,4148;.%1A....
0390h: 0C 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A ; .***************
03A0h: 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A ; ****************
03B0h: 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A ; ****************
03C0h: 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A ; ****************
03D0h: 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 0D 0A 0D ; *************...
03E0h: 0A 62 6C 61 68 20 62 6C 61 68 20 62 6C 61 68 0D ; .blah blah blah.
03F0h: 0A 0D 0A 0C 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A ; ....************

This block should be modified to:

02F0h: F8 00 FC 01 F8 00 0D 0A 0D 1B 28 73 30 70 30 73 ; ø.ü.ø.....(s0p0s
0300h: 33 62 31 32 68 34 31 30 31 54 1B 26 6C 32 61 30 ; 3b12h4101T.&l2a0
0310h: 6F 30 65 30 6C 38 64 38 38 46 0D 0A 1B 2A 70 30 ; o0e0l8d88F...*p0
0320h: 78 30 59 1B 2A 63 35 37 36 30 78 37 39 32 30 59 ; x0Y.*c5760x7920Y
0330h: 1B 2A 63 30 54 1B 25 31 42 53 50 31 3B 53 43 30 ; .*c0T.%1BSP1;SC0
0340h: 2C 33 2E 33 38 36 37 2C 30 2C 2D 33 2E 33 38 36 ; ,3.3867,0,-3.386
0350h: 37 2C 32 3B 49 52 30 2C 31 30 30 2C 30 2C 31 30 ; 7,2;IR0,100,0,10
0360h: 30 3B 53 50 31 3B 44 54 5E 2C 31 3B 53 44 32 2C ; 0;SP1;DT^,1;SD2,
0370h: 31 2C 34 2C 31 30 2C 35 2C 30 2C 36 2C 33 2C 37 ; 1,4,10,5,0,6,3,7
0380h: 2C 34 31 34 38 3B 1B 25 31 41 0D 0A 0D 0A 2A 2A ; ,4148;.%1A....**
0390h: 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A ; ****************
03A0h: 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A ; ****************
03B0h: 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A ; ****************
03C0h: 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A ; ****************
03D0h: 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 0D 0A 0D 0A 62 6C ; **********....bl
03E0h: 61 68 20 62 6C 61 68 20 62 6C 61 68 0D 0A 0D 0A ; ah blah blah....
03F0h: 0C 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A ; .***************

So the task is to remove the two bytes 1B 45 at byte offset 761 (hexadecimal 02F9) and the byte 0C at byte offset 912 (hexadecimal 0390) without removing any other byte 0C like the one at byte offset 1011 (hexadecimal 03F3).

The following command line can be used in a batch file for removing in such binary files containing ESC+E stored hexadecimal with the bytes 1B 45 and first Form Feed stored hexadecimal with the byte 0C:

for /R %%I in ("*.out") do call C:\qsi\jrepl.bat "\x1BE([\s\S]+?)\f" "$1" /M /F "%%I" /O -

The regular expression search string results in searching for

  • \x1BE ... a byte with hexadecimal value 1B followed by character E (case-sensitive) and
  • (...) ... with using a marking group
  • [\s\S] ... for a whitespace or a non-whitespace character, i.e. any character (or byte)
  • + ... one or more times
  • ? ... non-greedy
  • \f ... and a form feed.

The bytes between 1B 45 and 0C matched by the expression inside marking group are back-referenced in replace string with $1 to be kept in the binary files.

Mofi
  • 46,139
  • 17
  • 80
  • 143