5

Мне нужен пакетный скрипт для Windows, который делает следующее:

  1. выводит все имена файлов из каталога в текстовый файл (обычно от нескольких сотен до 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  

Результат многообещающий, но мне нужны строки, перечисленные в файле results.txt, а также счетчик, чтобы файл результатов выглядел так:

string1 = 3  
string2 = 5  
...  
string35 = 1 

Файл .csv также будет в порядке, и в этом случае мне понадобится следующий формат:

string1;3  
string2;5  
...  
string35;1  

Возможна ли такая вещь?

1 ответ1

2

Общее количество строк на строку

Пакетный скрипт (неявный)

@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" будет лучше или нет.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .