繁体   English   中英

递归循环到子文件夹并在文件中寻找子字符串

[英]Loop recursively into subfolders and look for a substring into files

我想创建一个脚本,该脚本以递归方式遍历D:\\MyFolder\\子文件夹,以找到多个名为MyFile.txt文件,然后在每个文件中查找关键字FROM并检索FROM和下一个分号之间的字符串;

MyFile.txt示例:

 LOAD Thing1, Thing2, Thing3, FROM Somewhere ; 

理想的结果是: Somewhere

(分号的位置;可以在另一行中)。

我做了一些尝试,但未成功编写正确的脚本:

@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% 
    )
)

如果无法批量完成,请告诉我可以轻松使用哪种语言。 我想最后有一个可执行脚本。

您的代码中存在一些问题:

  • for /Fdelims选项定义字符,定义用作解析文本文件的定界符的单词 要查找单词,请改用findstr (您可以使用其/N选项得出搜索字符串的位置/行号)。
  • for /Feol选项定义一个字符以忽略行,以防它出现在开头(或者仅在定界符之后)。
  • for /R中没有通配符( ?* ),则for /R实际上不会搜索文件(即括号之间的部分)。 dir /S命令可以,因此可以通过在dir /S周围包裹for /F循环来解决此问题。
  • 系统使用PATH变量来查找可执行文件,例如findstr ,因此您不能覆盖它。 请改用其他变量名。

这是我可能会做的方式(假设还必须返回关键字FROM之后的任何文本):

@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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM