Search code examples
batch-filefindstr

How to show the place and only the words found Findstr?


I wonder how do I show the location where the words were found in findstr?

My Code:

Set "LFiles=%temp%\Files\*.txt">nul 2>&1

Findstr /li /G:"List.txt" "%LFiles%">"Result.TxT"

(for /F %%a in (List.txt) do (
   Findstr /li /C:"%%a" "%LFiles%" > NUL
   if not errorlevel 1 echo %%a
))>"Result2.TxT"

List:

Disc
Music
Song
Album

Result:

DISC1312we7das67da
13dsdsa67dsahdsa7aMUSIC
dsadsdfdsaSONG1223234235

Result2:

Disc
Music
Song

The desired result in Result2:

--------------
Filelist1.txt
--------------
Song

--------------
Filelist2.txt
--------------
Song
Disc

--------------
Filelist3.txt
--------------
Disc
Music
Song

Note: the filenames are random

@Edit

I could make him show you what was found in each file...

Came here two problems:

  1. How do I show him the file names if they have spaces in the name?
  2. How do I join the results of the same file on a single line?

.

Dir /b "%temp%\Files\*.txt">Files2.txt

Set "LFiles=LFiles=%temp%\Files\*.txt">nul 2>&1

Findstr /li /G:"List.txt" "%LFiles%">"Result.TxT"

(for /F %%a in (Files2.txt) do (
(for /F %%b in (List.txt) do (
   Findstr /li /C:"%%b" "Result.txt" > NUL
   if not errorlevel 1 echo "%%a" "%%b"
))))>>"Result2.TxT"

Current result:

"File" "Disc"
"File" "Song"
"File" "Music"
"Files_and" "Disc"

The desired result

File 01.txt: Song, Music
File 02.txt: Music, Disc

or

File 01.txt:
Song
Music

File 02.txt:
Music
Disc

Solution

  • The solution below execute findstr command just one time per each word in List.txt file, so it should run faster. It also keep the results in "file" array for any further processing:

    @echo off
    setlocal EnableDelayedExpansion
    
    Set "LFiles=%temp%\Files\*.txt"
    
    for /F %%a in (List.txt) do (
       for /F "delims=" %%b in ('findstr /LIM /C:"%%a" "%LFiles%"') do (
          set "file[%%~Nb]=!file[%%~Nb]! %%a"
          set /A "word[%%a]+=1"
       )
    )
    
    (for /F "tokens=2* delims=[]=" %%a in ('set file[') do (
       echo --------------
       echo %%a.txt
       echo --------------
       for %%c in (%%b) do echo %%c
       echo/
    )) > Result2.txt
    
    ECHO RESULT IN REQUESTED FORMAT:
    TYPE RESULT2.TXT
    ECHO/
    ECHO/
    ECHO VALUES STORED IN "FILE" ARRAY:
    SET FILE[
    
    ECHO WORD COUNT:
    SET WORD[
    

    EDIT: New method that count the number of each word per file, as requested in comment.

    @echo off
    setlocal EnableDelayedExpansion
    
    Set "LFiles=%temp%\Files\*.txt"
    
    rem Accumulate counts of all file/word combinations in a two-dimensional array
    for /F %%a in (List.txt) do (
       for /F "delims=:" %%b in ('findstr /LI /C:"%%a" "%LFiles%"') do (
          set /A "count[%%~Nb][%%a]+=1"
       )
    )
    
    rem Group word counts for the same file
    for /F "tokens=2,3* delims=[]=" %%a in ('set count[') do (
       set "file[%%a]=!file[%%a]!, %%b (%%c)"
    )
    
    rem Show the final result
    (for /F "tokens=2* delims=[]=" %%a in ('set file[') do (
       set "line=%%b"
       echo %%a.txt = !line:~2!
    )) > Result2.TxT
    
    
    ECHO THE COUNT ARRAY:
    SET COUNT[
    ECHO/
    ECHO THE FILE ARRAY:
    SET FILE[
    

    This new method count the number of matching lines in each file. If the same word may appear two or more times in a line, it will be counted just as one. This point may be fixed in order to count individual words, but the resulting code will be much slower...