1

It seems for me a very simple question, however I am struggling a lot with this and don't find an answer yet. My aim is to count occurences of a specific string in a file. I do or try to do this using following command:

for /f "tokens=2 delims=;" %%a in ('path to file with searchstring') do (
   set count=('path to file I am searching in' find /c "%%a")
   if !count! NEQ 0 echo !count!
)

Seems straightforward for me however the second line seems to be wrong as the script exits. I want to save the result of findin a var because I only wants to outpout Nonzero resutls.

Compo
  • 36,585
  • 5
  • 27
  • 39
SRel
  • 383
  • 1
  • 11
  • 1. Change to outer loop to `for /F "usebackq tokens=2 delims=;" %%a in ("path to file with searchstring") do ( ... )`. 2. The second line should read `for /F %%c in ('^< "path to file I am searching in" find /C "%%a"') do set "count=%%c"`. 3. You should preinitialise the count variable like `set "count=0"`. 4. Type `for /?` into a command prompt window and (re-)read its help... – aschipfl Jan 30 '20 at 22:44
  • thank you @aschipfl that seems to work. can you schortly explayin what ```^<``` does? – SRel Jan 30 '20 at 22:53
  • However it seems that there now is a massive drop in runtime adding the seconde ```FOR``` but I will have a try thank you – SRel Jan 30 '20 at 22:54
  • Concerning the `^<`: You could do `find /C "search string" "file path"` to get the count of matching lines, but there appears more than just the count like a header; when you use [input redirection `<`](https://ss64.com/nt/syntax-redirection.html) to provide the file to `find` the pure count is returned; `< "file path" find /C "seach string"`; since the result of that command line is captured by [`for /F`](https://ss64.com/nt/for_cmd.html) you need to [escape (`^`)](https://ss64.com/nt/syntax-esc.html) the redirection to not become applied to `for /F`... – aschipfl Jan 30 '20 at 23:00
  • Concerning performance: for every line in the file with the search string(s), the inner `for /F` loop iterates once and starts a new command prompt (`cmd.exe`) instance which actually executes `find`; maybe the speed could be increased, but it depends on your data (formats); perhaps you want to [edit] the question and share some sample data for both data files (search strings and text to be searched)? – aschipfl Jan 30 '20 at 23:05
  • Thanks for your help. I mentioned a more detailed look in my question from yesterday:[link](https://stackoverflow.com/questions/59968084/batch-write-text-from-file-into-local-variable-error) As I have much lines to process I keep this in mind a bit @aschipfl – SRel Jan 30 '20 at 23:14
  • 1
    Note: this counts the *lines* that contain the search string, not the occurrences of the search string. If the search string occurs more than once in a single line, they are counted as one (line). Might or might not matter for you, but you should be aware of that. – Stephan Jan 31 '20 at 08:45
  • Do you want all the occurrences of a string or all occurrences of a substring in strings? – Gerhard Jan 31 '20 at 09:28
  • @Stephan thanks. indeed this is sufficient as the words I am looking for occur only once in a line in a specific location. One other problem I had that I found out the ```Find```command searches for substring and so also count lines in which the string combination exist inside other words. However I need the EXACT match so to cope with this I am now using this workaround: `findstr /r /c:"\<%%a\>" TlsTrace.txt | find /c /v "GarbageStringDefNotInYourResults"` – SRel Jan 31 '20 at 19:45
  • @GerhardBarnard I watnt he occurences of the exact match, so when Iam looking for `RM` the word `RM4` should not be counted – SRel Jan 31 '20 at 19:48
  • Where do you take your search string from? Your `for` loop currently searches the file for the second token of *every line*. Is that really what you want to do (if not, what exactly do you want to do)? – Stephan Feb 01 '20 at 08:56
  • [possible duplicate](https://stackoverflow.com/questions/59292378/is-possible-to-set-an-adb-command-as-a-variable-in-batch) – Stephan Feb 01 '20 at 15:05

1 Answers1

0

Here's an example using , for better word matching, (It uses the filenames from your previous question):

@(For /F "UseBackQTokens=2Delims=;" %%G In ("classID.txt")Do @(Set "count=0"
        For /F %%H In ('^""%__AppDir__%findstr.exe" /IN "\<%%G\>" "trc.txt"^"'
        )Do @(Set /A count+=1)&SetLocal EnableDelayedExpansion
        If !count! Gtr 0 (Echo %%G: !count!)&Endlocal))&Pause

Here it is fully parenthesized over multiple lines for you to better understand:

@Echo Off
For /F "UseBackQ Tokens=2 Delims=;" %%G In (
    "classID.txt"
) Do (
    Set "count=0"
    For /F %%H In (
        '^""%__AppDir__%findstr.exe" /I /N "\<%%G\>" "trc.txt"^"'
    ) Do (
        Set /A count +=1
    )
    SetLocal EnableDelayedExpansion
    If !count! Gtr 0 (
        Echo %%G: !count!
    )
    Endlocal
)
Pause

And a fully parenthesized example of it outputting the results to a file named results.txt:

@Echo Off
(
    For /F "UseBackQ Tokens=2 Delims=;" %%G In (
        "classID.txt"
    ) Do (
        Set "count=0"
        For /F %%H In (
            '^""%__AppDir__%findstr.exe" /IN "\<%%G\>" "trc.txt"^"'
        ) Do (
            Set /A count +=1
        )
        SetLocal EnableDelayedExpansion
        If !count! Gtr 0 (
            Echo %%G: !count!
        )
        Endlocal
    )
)>"results.txt"
Compo
  • 36,585
  • 5
  • 27
  • 39