Batch Script to find 2 strings and count individual values

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

Batch Script to find 2 strings and count individual values

Post by MigrationUser »

16 Jan 2014 15:26
debojit_pal

Hi Gurus,

I am a newbie to batch scripting, in fact to be frank I do not know anything about batch scripting. There is an urgent requirement in Windows where I have to write certain batch commands (and scripts) to do a job. Your help will be hugely appreciated.

Requirement - I have a text file in the below format.

EXPLANATION
asedas JDXA dsfad jihhsad JDXA sad
jkhdf JDXA asdfasdf
EXPLANATION
EXPLANATION
EXPLANATION
kjasdfhkjf JDXA lhlsdf JDXA
EXPLANATION
dsfjlkds JDXA JDXA
JDXA safsda
EXPLANATION
EXPLANATION
klsjdfl JDXA
EXPLANATION

Okay, now there are two parts to it -
1. Count the total number of occurrences of the string "EXPLANATION" in the file. This part is apparently easy and I can code it.
2. Between two EXPLANATION's in the file I have to check if the string "JDXA" is occurring. If yes, then count it only once else don't count it and find the total number cases where this is happening.

The final output file should have the counts only. Like -
EXPLANATION 8
JDXA 4

The 2nd part is tricky and I need help and, to elaborate it (just in case I was not clear earlier) - The total count of "JDXA" is not needed. I want the count of how many times we have "JDXA" at least once between two EXPLANATION's.

Any help would be appreciated.

Thanks
Debojit.

----------------------------

#2 16 Jan 2014 15:52
debojit_pal

Okay, a quick addition if it helps - The string "JDXA" will occur at least once in each line of the file wherever we do not have "EXPLANATION".

----------------------------

#3 16 Jan 2014 16:30
foxidrive

Re: Batch Script to find 2 strings and count individual values

If each two sets of EXPLANATION make one record then this line is not counted, as it occurs between records. Is that right?

kjasdfhkjf JDXA lhlsdf JDXA

Last edited by foxidrive (16 Jan 2014 16:39)

----------------------------

#4 16 Jan 2014 17:30
debojit_pal

Hi Foxidrive, that is not true. That record is counted. The need is to find out the number of cases where "JDXA" occurs (at least once) between any two EXPLANATION's.

In the file shown in the 1st post, the number of counts of "JDXA" should come out as 4. Because there are 4 sets of occurrences where "JDXA" occurs between any two EXPLANATION's.

Hope this clears your doubt.

----------------------------

#5 16 Jan 2014 20:29
Aacini

Code: Select all

@echo off
setlocal EnableDelayedExpansion

set /A explanation=0, jdxa=0
set "firstJdxa="
for /F "delims=" %%a in (input.txt) do (
   set "line=%%a"
   rem If this line have "explanation"
   if "!line:EXPLANATION=!" neq "!line!" (
      rem Count it and set "first jdxa" flag
      set /A explanation+=1, firstJdxa=1
   rem else If this line have "jdxa"
   ) else if "!line:JDXA=!" neq "!line!" (
      rem If it is the first JDXA after a EXPLANATION
      if defined firstJdxa (
         rem Count it end reset "first jdxa"
         set /A jdxa+=1
         set "firstJdxa="
      )
   )
)
echo EXPLANATION %explanation%
echo JDXA %jdxa%
The only problem is what happens if is there an JDXA before the first EXPLANATION, or if the file end with JDXA with no posterior EXPLANATION. This solution does not count the first case, but counts the second one...

Antonio

Last edited by Aacini (16 Jan 2014 20:31)

----------------------------

#6 16 Jan 2014 23:06
dbenham

I am assuming you only want to count EXPLANATION when it appears as the entire line.

Here is a case sensitive solution that properly ignores any JDXA before the first EXPLANATION or after the last EXPLANATION.

Code: Select all

@echo off
setlocal
set /a "jdxa=foundJDXA=0"
set "explanation="
for /F "delims=" %%A in (test.txt) do (
  if %%A == EXPLANATION (
    set /a "explanation+=1, jdxa+=foundJDXA, foundJDXA=0"
  ) else if defined explanation echo %%A|findstr "JDXA" >nul && set "foundJDXA=1"
)
echo EXPLANATION %explanation%
echo JDXA %jdxa%
Here is a solution that ignores case, and still ignores JDXA that occurs before the first EXPLANATION or after the last EXPLANATION. I opted to use the SET search and replace method because I believe it is faster than FIND or FINDSTR. However, this may fail if the file contains the ! character. In which case, revert back to the original, but use the /I option for both the IF statement and the FINDSTR.

Code: Select all

@echo off
setlocal enableDelayedExpansion
set /A "explanation=jdxa=foundJDXA=0"
for /F "delims=" %%A in (test.txt) do (
  if /i %%A == EXPLANATION set /a "explanation+=1, jdxa+=foundJDXA, foundJDXA=0"
  if !explanation! gtr 0 (
    set "line=%%A"
    if "!line:JDXA=!" neq "!line!" set "foundJDXA=1"
  )
)
echo EXPLANATION %explanation%
echo JDXA %jdxa%
**UPDATE**

If it is true that every non-EXPLANATION line contains at least one JDXA, then the code is even simpler. Here is a case sensitive search

Code: Select all

@echo off
setlocal
set /a "jdxa=foundJDXA=0"
set "explanation="
for /F "delims=" %%A in (test.txt) do (
  if %%A == EXPLANATION (
    set /a "explanation+=1, jdxa+=foundJDXA, foundJDXA=0"
  ) else if defined explanation set "foundJDXA=1"
)
echo EXPLANATION %explanation%
echo JDXA %jdxa%
Dave Benham

Last edited by dbenham (16 Jan 2014 23:13)

----------------------------

#7 17 Jan 2014 04:05
foxidrive

Solution 3 Dave. Is this line doing something special?

Code: Select all

set /a "jdxa=foundJDXA=0"
EDIT: I found out what it does, it initialises a set of variables in one command. Neva seen that b4.

Last edited by foxidrive (17 Jan 2014 04:26)

----------------------------

#8 17 Jan 2014 06:03
debojit_pal

Antonio - You are God!! \o/

The script works perfectly and, no the file will not begin with JDXA but might end with JDXA and your code won't break in that case.

You saved my day, I was supposed to deliver this today.

Thank you. Debojit.

Last edited by debojit_pal (17 Jan 2014 06:14)

----------------------------

#9 17 Jan 2014 06:13
debojit_pal


Dave - Your code works flawlessly for the input which I had mentioned in my 1st post. And, yes it is tue that every non-EXPLANATION line contains at least one JDXA.

But if the file ends with a JDXA line then it can't count the last occurrence. I am hoping the file won't end with a JDXA line but just in case it does, I'll try adding to your code and see if it works.

Thank you. Debojit.

Last edited by debojit_pal (17 Jan 2014 06:15)

----------------------------

#10 17 Jan 2014 07:38
dbenham


@debojit_pal

I went out of my way to meet the requirements as you described them (only count if JXA between two EXPLANATIONs).

If you want to count a trailing JDXA then you can simply add set /a jdxa+=foundJDXA after the termination of the outermost loop. Or structure the logic more like Aacini's solution.

Dave Benham

----------------------------

#11 17 Jan 2014 11:41
debojit_pal

Dave, absolutely agreed and appreciated too.

I should have been clearer with the requirements. Both Aacini's and your codes work perfectly now.

Thanks again guys for saving my day.
Post Reply