Reputation: 95
I would like to create a script that loops reccursively through subfolders of D:\MyFolder\
for example, to find multiple files named MyFile.txt
then look into each file for the keyword FROM
and retrieve the string between the FROM
and the next semicolon ;
.
Sample of MyFile.txt
:
LOAD Thing1, Thing2, Thing3, FROM Somewhere ;
The desired result is: Somewhere
.
(The position of the semicolon ;
can be in another line).
I did some tries but I did not succeed in writing a correct script:
@echo off
SET PATH="D:\MyFolder\"
FOR /R %PATH% %%f IN (MyFile.txt) DO (
FOR /F "delims=FROM eol=;" %%A in (%%f) do (
set str=%%A
ECHO %str%
)
)
If it can't be done in batch, please let me know in which language I can do it easily. I would like to have an executable script in the end.
Upvotes: 0
Views: 238
Reputation: 34909
There are some issues in your code:
delims
option of for /F
defines characters but not words to be used as delimiter for parsing text files. To find a word, use findstr
instead (you could use its /N
option to derive the position/line number of the search string).eol
option of for /F
defines a character to ignore a line in case it occurs at the beginning (or it is preceded by delimiters only).for /R
does actually not search for files in case there are no wild-cards (?
, *
) in the set (that is the part in between parentheses). The dir /S
command does, so you can work around this by wrapping a for /F
loop around dir /S
.PATH
variable is used by the system to find executables, like findstr
, so you must not overwrite it; use a different variable name instead.Here is the way I would probably do it (supposing any text following the keyword FROM
needs to be returned also):
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_ROOT=D:\MyFolder" & rem // (root directory of the tree to find files)
set "_FILE=MyFile.txt" & rem // (name of the files to find in the tree)
set "_WORD=FROM" & rem // (keyword to be searched within the files)
set "_CHAR=;" & rem // (character to be searched within the files)
rem // Walk through the directory tree and find matching files:
for /F "delims=" %%F in ('dir /B /S "%_ROOT%\%_FILE%"') do (
rem // Retrieve the line number of each occurrence of the keyword:
for /F "delims=:" %%N in ('findstr /N /I /R "\<%_WORD%\>" "%%~F"') do (
rem // Process each occurrence of the keyword in a sub-routine:
call :PROCESS "%%~F" %%N
)
)
endlocal
exit /B
:PROCESS
rem // Ensure the line number to be numeric and build `skip` option string:
set /A "SKIP=%~2-1"
if %SKIP% GTR 0 (set "SKIP=skip^=%SKIP%") else set "SKIP="
rem // Read file starting from line containing the found keyword:
set "FRST=#"
for /F usebackq^ %SKIP%^ delims^=^ eol^= %%L in ("%~1") do (
set "LINE=%%L"
setlocal EnableDelayedExpansion
rem // Split off everything up to the keyword from the first iterated line:
if defined FRST set "LINE=!LINE:*%_WORD%=!"
rem /* Split read line at the first occurrence of the split character;
rem the line string is augmented by preceding and appending a space,
rem so it is possible to detect whether a split char. is there: */
for /F "tokens=1,* delims=%_CHAR% eol=%_CHAR%" %%S in (" !LINE! ") do (
endlocal
set "TEXT=%%S"
set "RMND=%%T"
set "ITEM=%~1"
setlocal EnableDelayedExpansion
rem // Check whether a split character is included in the line string:
if not defined RMND (
rem // No split char. found, so get string without surrounding spaces:
set "TEXT=!TEXT:~1,-1!"
) else (
rem // Split char. found, so get string without leading space:
set "TEXT=!TEXT:~1!"
)
rem // Trimm leading white-spaces:
for /F "tokens=*" %%E in ("!TEXT!") do (
endlocal
set "TEXT=%%E"
setlocal EnableDelayedExpansion
)
rem // Return string in case it is not empty:
if defined TEXT echo(!ITEM!;!TEXT!
rem // Leave sub-routine in case split char. has been found:
if defined RMND exit /B
)
endlocal
set "FRST="
)
exit /B
Upvotes: 1