1

This question is pretty similar to this question.


I've been stuck trying to count how many a string appears between brackets. Consider the follow text file(although it looks like a .bat script)

(
echo a
echo b
echo c
)
echo z

In the file above, we can see 4 echo, but I only want to count the ones inside the brackets(the result should be 3)


for /f "delims=][  tokens=2" %%H in ('FART.exe -c -i -p %File% ^( a') do set /a count+=1

This code works, but only counts 1, because I couldn't figure out how to count multiple appearances. Please help me, any help will be appreciated.


Edit - 5/7/17

You can assume

  • There would be only 1 echo on each line.
  • Parentheses are not nested
  • echo would not appear on the same line as parentheses
    • Bonus if you can make your script count the echo on the same line of parentheses
2
  • You haven't properly defined your problem. Can there be multiple ECHO on one line? Can parentheses be nested? Can ECHO appear on same line as parentheses? Commented Jul 4, 2017 at 16:15
  • @dbemham good questions, I will edit my post. Commented Jul 5, 2017 at 2:07

3 Answers 3

1

For those expecting a batch-file, who have more respect for the rules than SteveFest, here is a basic example, (probably not the most efficient, but hey this sort of task wouldn't be designed for huge files anyhow):

@Echo Off
For /F "Tokens=1*Delims=:" %%A In ('FindStr/N $ "%~n0.txt"') Do (
    If "%%B"=="(" If Not Defined FL Set/A FL=%%A+1
    If "%%B"==")" If Not Defined LL Set/A LL=%%A-1)
Set "i=0"
If FL LEq LL For /L %%A In (%FL%,1,%LL%) Do For /F "Tokens=1*Delims=:" %%B In (
    'FindStr/N $ "%~n0.txt"') Do If "%%B"=="%%A" If Not "(%%C"=="(" Set/A i+=1
Echo( [%i%]
Timeout -1
Sign up to request clarification or add additional context in comments.

5 Comments

This solution worked for me, but I also noticed a typo in your code - "Tokens=1*Delims=:" should be changed.
My script is correct, an additional space character in each of those locations is not necessary!
That's weird, on my Win10, it doesn't work correctly without the space in between this two options.
Just because I wanted to be sure, I've tested it without the spaces on Windows 10.0.14393, and found it to work without issue.
I am using Win 10 Build 15063, it requires the space to work for me(by the way, I do not use English Windows)
1

You can try this regex:

echo(?=((?!\().)*\))

The number of match of the word 'echo' inside bracket will be your count

Regex101 Demo

As, windows batch won't support lookaheads thus you may use python script for the same purpose instead of using batch if you have to apply regex. Apart, you may try non regex solution in batch

This block will do: (run here )

regex = r"echo(?=((?!\().)*\))"
matches = re.finditer(regex, test_str, re.DOTALL)
count=0

for match in matches:
        count +=1
print(count)

where test_str is the content of the file

8 Comments

Let me test this in findstr, will report result to you later.
This seems to work on bash, not batch-file, batch-file's regex support are poor...
Oh sad, then You may use python script for the same purpose instead of using batch if you have to apply regex. Apart, you may try non regex solution in batch
may I ask how do I implement this in Python? I have 0 experience in python.
@RizwanM.Tuman, btw, I tested the py script on my PC, seems working fine.
|
1

Your specifications are incomplete because, as stated, this problem can be reduced to: Count the number of lines between left paren and right paren:

@echo off
setlocal

set "open="
for /F "delims=:" %%a in ('findstr /N "( )" test.txt') do (
   if not defined open (
      set "open=%%a"
   ) else (
      set /A count=%%a-open-1
   )
)
echo %count%

1 Comment

I was going to use exactly this idea but couldn't ignore the possibility of a closing parenthesis existing in a line in its own before an opening one. I also realised that it would output the number of lines between the parentheses not the number of entries between them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.