在批处理脚本中使用“查找”命令写入文件

Mat*_*ata 5 windows batch

我需要一个执行以下操作的 Windows 批处理脚本:

  1. 将目录中的所有文件名转储到 .txt 文件(通常是几百到 50 万个文件)
  2. 在输出文件中搜索特定字符串(其中大约 35 个),对它们进行计数并使用结果创建另一个文件

鉴于我在今天之前没有编写任何脚本,我想出了以下内容:

@echo off  
dir /b > maps.txt  
(  
find /c /i "string1" maps.txt  
find /c /i "string2" maps.txt  
...  
find /c /i "string35" maps.txt  
)  > results.txt  
Run Code Online (Sandbox Code Playgroud)

结果很有希望,但我需要 results.txt 文件中枚举的字符串以及计数,以便结果文件如下所示:

string1 = 3  
string2 = 5  
...  
string35 = 1 
Run Code Online (Sandbox Code Playgroud)

.csv 文件也可以,在这种情况下,我需要以下格式:

string1;3  
string2;5  
...  
string35;1  
Run Code Online (Sandbox Code Playgroud)

这样的事情可能吗?

Vom*_*yle 3

每个字符串的总字符串计数

批处理脚本(隐式)

@ECHO OFF

::: If this file exists, delete it 
IF EXIST "Results.txt" DEL /Q /F "Results.txt"

::: Bare format DIR command listing ONLY filename.extension 
DIR /B > maps.txt

::: Please go to command line and type FOR /? and look through there for the FOR /F explanations
::: This is saying for each line in strings.txt do a FIND /I for each string in maps.txt and if FIND /I finds a string, then CALL the StringCountRoutine and pass the string found as the first argument to the CALL :label (:StringCountRoutine in this instance)
::: Please note that is a string IS NOT FOUND then there will be no count and not a zero unfortunately so it's implied that is the string is not in the results.txt file, then the count of that string is zero
FOR /F "TOKENS=*" %%S IN (Strings.txt) DO (FIND /I "%%S" maps.txt && CALL :StringCountRoutine "%%~S")
::: GOTO EOF needed here to pass control back to the CALLER or END once loop is complete to it doesn't move on to logic beneath which should only be called
GOTO EOF

:StringCountRoutine
::: This is saying the TOKEN count is three and each token to count (the DELIMITER) are colons and spaces ("DELIMS=: ") so for example this (---------- MAPS.TXT: 14) has two spaces and one colon so only have the variable be what's left afterwards which is just the number when set this way
::: The first argument is passed to the FIND /C command as listed below and also the ECHO command afterwards
FOR /F "TOKENS=3DELIMS=: " %%A IN ('FIND /C "%~1" maps.txt') DO (ECHO %~1 = %%A >> Results.txt)
::: GOTO EOF needed here to pass control back to the CALLER or END once loop is complete to it doesn't move on to logic beneath which should only be called
GOTO EOF
Run Code Online (Sandbox Code Playgroud)

在一个文件中搜索字符串并在另一个文件中查找相同的字符串

下面是两个示例,展示了一种执行您需要的方法,我相信,但您希望将string值保存到单独的文本文件中,其中每个字符串在该文件中的每行表示。只要 位于该行TOKENS=*FOR /F,它就会读取带或不带空格的每一行作为string您在文件中查找的值map.txt

隐式定义的脚本

@ECHO OFF

::: If this file exists, delete it 
IF EXIST "Results.txt" DEL /Q /F "Results.txt"

::: Bare format DIR command listing ONLY filename.extension 
DIR /B > maps.txt

::: Set seq variable to 1 for the first sequence number
SET seq=1

::: Please go to command line and type FOR /? and look through there for the FOR /F explanations
::: This is saying for each line in strings.txt do a FIND /I for each string in maps.txt and if FIND /I finds a string, then CALL the SeqAdditionRoutine and pass the string found as the first argument to the CALL :label (:SeqAdditionRoutine in this instance)
FOR /F "TOKENS=*" %%S IN (Strings.txt) DO (FIND /I "%%S" maps.txt && CALL :SeqAdditionRoutine "%%~S")
::: GOTO EOF needed here to pass control back to the CALLER or END once loop is complete to it doesn't move on to logic beneath which should only be called
GOTO EOF

:SeqAdditionRoutine
::: This is saying FIND /I but with first argument passed as the string (same as above FIND /I but the first argument is passed here), and if successful (the double AND) ECHO the string equals 1 (or the sequence number variable value) to results.txt
FIND /I "%~1" maps.txt && ECHO %~1 = %seq% >> results.txt
::: This is saying (see SET /?) whatever seq variable is set to, ADD one to it and set it to this new value for whatever adding one to it will make it when it goes to EOF, it'll loop the next command (the CALLing loop) with this new value until it is successful in finding a strings and comes back down here again
SET /A seq=%seq%+1
::: GOTO EOF needed here to pass control back to the CALLER or END once loop is complete to it doesn't move on to logic beneath which should only be called
GOTO EOF
Run Code Online (Sandbox Code Playgroud)

显式定义的脚本

@ECHO OFF

SET stringlist=C:\folder\folder\Strings.txt
SET mapsfile=C:\folder\folder\Maps.txt
SET resultsfile=C:\folder\folder\Results.txt

IF EXIST "%resultsfile%" DEL /Q /F "%resultsfile%"

DIR /B > "%mapsfile%"

SET seq=1
FOR /F "TOKENS=*" %%S IN (%stringlist%) DO (FIND /I "%%S" "%mapsfile%" && CALL :SeqAdditionRoutine "%%~S")
GOTO EOF

:SeqAdditionRoutine
FIND /I "%~1" "%mapsfile%" && ECHO %~1 = %seq% >> "%resultsfile%"
SET /A seq=%seq%+1
GOTO EOF
Run Code Online (Sandbox Code Playgroud)

更新

我从隐式脚本中对此进行了测试,它按预期工作。。。

我只得到了string = number那些在 中找到匹配的字符串Strings.txt,而不是从maps.txt或同一目录中的其他 txt 文件中得到的任何字符串。

我在文件中定义的字符串Strings.txt确实包含数字,因此FIND /V我确实注意到它string1也匹配string10string11如我的示例所示。我不确定这对您来说是否是一个问题,或者什么与values您的搜索字符串值标准相匹配,但这可能是您申请时需要考虑的问题。我不确定是否FINDSTR /LFINDSTR /I /C:"%~1"更好。