我需要一个适用于 Windows 的批处理脚本来执行以下操作:
- 将目录中的所有文件名转储到 .txt 文件中(通常几百到五万个文件)
- 在输出文件中搜索特定字符串(大约 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
结果很有希望,但我需要在 results.txt 文件中枚举的字符串以及计数,以便结果文件看起来像这样:
string1 = 3
string2 = 5
...
string35 = 1
.csv 文件也可以,在这种情况下我需要以下格式:
string1;3
string2;5
...
string35;1
这种事可能吗?
答案1
每串总串数
批处理脚本(隐式)
@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
在一个文件中搜索字符串并在另一个文件中查找相同的字符串
下面是两个示例,展示了一种我认为可以满足您需求的方法,但您需要将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
明确定义的脚本
@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
更新
我从隐式脚本对此进行了测试并且它按预期工作。。。
我只得到了string = number
在中找到匹配的字符串,Strings.txt
而没有得到来自maps.txt
同一目录中的其他 txt 文件的任何字符串。
我在文件中定义的字符串Strings.txt
确实包含数字,因此FIND /V
我注意到它string1
也匹配string10
,string11
就像我的例子一样。我不确定这对你来说是否是个问题,或者什么values
会匹配你的搜索字符串值条件,但这可能是你在申请时需要考虑的事情。我不确定或FINDSTR /L
是否FINDSTR /I /C:"%~1"
会更好。