Как вы проходите через каждую строку в текстовом файле, используя пакетный файл Windows? - PullRequest
216 голосов
/ 01 октября 2008

Я хотел бы знать, как циклически проходить каждую строку в текстовом файле с помощью пакетного файла Windows и обрабатывать каждую строку текста подряд.

Ответы [ 11 ]

276 голосов
/ 02 октября 2008

Посты ниже очень помогли, но не сделали то, что я сказал в своем вопросе, где мне нужно было обработать всю строку в целом. Вот что я нашел для работы.

for /F "tokens=*" %%A in (myfile.txt) do [process] %%A

Ключевое слово токенов со звездочкой (*) вытянет весь текст для всей строки. Если вы не поставите звездочку, она будет тянуть только первое слово в строке. Я предполагаю, что это связано с пробелами.

Для команды на TechNet

Я ценю все посты!


Если в пути к файлу есть пробелы, вам нужно использовать usebackq. Например.

for /F "usebackq tokens=*" %%A in ("my file.txt") do [process] %%A
54 голосов
/ 01 октября 2008

Из справки командной строки Windows:

Чтобы проанализировать файл, игнорируя закомментированные строки, введите:

for /F "eol=; tokens=2,3* delims=," %i in (myfile.txt) do @echo %i %j %k

Эта команда анализирует каждую строку в Myfile.txt, игнорируя строки, начинающиеся с точки с запятой и передавая второй и третий токены из каждой строки в тело FOR (токены разделяются запятыми или пробелами). Тело оператора FOR ссылается на% i, чтобы получить второй токен,% j, чтобы получить третий токен, и% k, чтобы получить все оставшиеся токены.

Если имена файлов, которые вы вводите, содержат пробелы, используйте кавычки вокруг текста (например, «Имя файла»). Чтобы использовать кавычки, вы должны использовать usebackq. В противном случае кавычки интерпретируются как определение литеральной строки для анализа.

Кстати, вы можете найти файл справки командной строки в большинстве систем Windows по адресу:

 "C:\WINDOWS\Help\ntcmds.chm"
31 голосов
/ 04 мая 2010

В пакетном файле вы ДОЛЖНЫ использовать %% вместо %: (Тип help for)

for /F "tokens=1,2,3" %%i in (myfile.txt) do call :process %%i %%j %%k
goto thenextstep
:process
set VAR1=%1
set VAR2=%2
set VAR3=%3
COMMANDS TO PROCESS INFORMATION
goto :EOF

Что это делает: "Do call: process %% i %% j %% k" в конце команды for передает информацию, полученную в команде for из myfile.txt, в подпрограмму "process".

Когда вы используете команду for в пакетной программе, вам нужно использовать двойные знаки% для переменных.

В следующих строках эти переменные передаются из команды for в подпрограмму процесса и позволяют обрабатывать эту информацию.

set VAR1=%1
 set VAR2=%2
 set VAR3=%3

У меня есть довольно продвинутые способы использования этой точной настройки, которыми я хотел бы поделиться, если понадобятся дополнительные примеры. При необходимости добавьте в EOL или Delims все необходимое.

24 голосов
/ 23 января 2012

Улучшение первого ответа "ЗА / Ф ..": Что мне нужно было сделать, это вызвать выполнить каждый скрипт, указанный в MyList.txt, чтобы он работал для меня:

for /F "tokens=*" %A in  (MyList.txt) do CALL %A ARG1

- ИЛИ, если вы хотите сделать это в несколько строк:

for /F "tokens=*" %A in  (MuList.txt) do (
ECHO Processing %A....
CALL %A ARG1
)

Edit: приведенный выше пример предназначен для выполнения цикла FOR из командной строки; из пакетного скрипта необходимо добавить дополнительный%, как показано ниже:

---START of MyScript.bat---
@echo off
for /F "tokens=*" %%A in  ( MyList.TXT) do  (
   ECHO Processing %%A.... 
   CALL %%A ARG1 
)
@echo on
;---END of MyScript.bat---
21 голосов
/ 28 мая 2013

@ Ответ МрКрауса поучителен. Далее, позвольте мне добавить, что , если вы хотите загрузить файл, расположенный в том же каталоге , что и пакетный файл, добавьте к имени файла префикс% ~ dp0. Вот пример:

cd /d %~dp0
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A

NB: : Если в имени файла или каталога (например, myfile.txt в приведенном выше примере) есть пробел (например, «my file.txt» или «c: \ Program Files»), используйте :

for /F "tokens=*" %%A in ('type "my file.txt"') do [process] %%A

, с ключевым словом type , вызывающим программу type, которая отображает содержимое текстового файла. Если вы не хотите испытывать накладные расходы при вызове команды type, вам следует изменить каталог на каталог текстового файла. Обратите внимание, что тип по-прежнему требуется для имен файлов с пробелами.

Надеюсь, это кому-нибудь поможет!

14 голосов
/ 18 июля 2013

Принятый ответ хорош, но имеет два ограничения.
Он сбрасывает пустые строки и строки, начинающиеся с ;

Чтобы прочитать строки любого контента, вам нужна техника переключения с отложенным расширением.

@echo off
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ text.txt"`) do (
    set "var=%%a"
    SETLOCAL EnableDelayedExpansion
    set "var=!var:*:=!"
    echo(!var!
    ENDLOCAL
)

Findstr используется для добавления к каждой строке префикса с номером строки и двоеточием, поэтому пустые строки больше не являются пустыми.

DelayedExpansion необходимо отключить при доступе к параметру %%a, в противном случае восклицательные знаки ! и каретки ^ будут потеряны, так как они имеют особые значения в этом режиме.

Но для удаления номера строки из строки необходимо включить отложенное расширение.
set "var=!var:*:=!" удаляет все до первого двоеточия (использование delims=: удалит также все двоеточия в начале строки, а не только один из findstr).
Endlocal снова отключает отложенное расширение для следующей строки.

Единственным ограничением теперь является ограничение длины строки ~ 8191, но, похоже, нет способа преодолеть это.

13 голосов
/ 12 августа 2009

Или вы можете исключить опции в кавычках:

FOR /F %%i IN (myfile.txt) DO ECHO %%i
9 голосов
/ 01 октября 2008

Вот файл bat, который я написал для выполнения всех сценариев SQL в папке:

REM ******************************************************************
REM Runs all *.sql scripts sorted by filename in the current folder.
REM To use integrated auth change -U <user> -P <password> to -E
REM ******************************************************************

dir /B /O:n *.sql > RunSqlScripts.tmp
for /F %%A in (RunSqlScripts.tmp) do osql -S (local) -d DEFAULT_DATABASE_NAME -U USERNAME_GOES_HERE -P PASSWORD_GOES_HERE -i %%A
del RunSqlScripts.tmp
5 голосов
/ 01 октября 2008

Если у вас Windows семейства NT (с оболочкой cmd.exe), попробуйте команду FOR / F .

2 голосов
/ 14 октября 2018

Принятый ответ, используя cmd.exe и

for /F "tokens=*" %F in (file.txt) do whatever "%F" ...

работает только для "обычных" файлов. Это терпит неудачу с огромными файлами.

Для больших файлов вам может понадобиться Powershell и что-то вроде этого:

[IO.File]::ReadLines("file.txt") | ForEach-Object { whatever "$_" }

или, если у вас достаточно памяти:

foreach($line in [System.IO.File]::ReadLines("file.txt")) { whatever "$line" } 

Это сработало для меня с файлом размером 250 МБ, содержащим более 2 миллионов строк, где команда for /F ... застряла после нескольких тысяч строк.

О различиях между foreach и ForEach-Object см. Знакомство с ForEach и ForEach-Object .

(кредиты: Считывание файлов построчно в PowerShell )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...