Как вы просматриваете каждую строку в текстовом файле с помощью командного файла Windows?

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


person Mr. Kraus    schedule 01.10.2008    source источник


Ответы (12)


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

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

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

для команд в TechNet


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

for /F "usebackq tokens=*" %%A in ("my file.txt") do [process] %%A
person Mr. Kraus    schedule 02.10.2008
comment
Небольшое дополнение: чтобы эта работа работала из командной строки в интерактивном режиме, замените %%A на %A в приведенной выше команде. В противном случае вы получите %%A was unexpected at this time.. - person vadipp; 12.11.2012
comment
К вашему сведению, если вам нужно выполнить многострочную команду, после DO вы можете поставить открытую круглую скобку (а несколькими строками позже закончить ее закрывающей круглой скобкой) - и вы можете просто поместить свой блок кода внутри них (с отступом до ваши вкусы). - person BrainSlugs83; 27.01.2013
comment
Если у вас есть проблемы с файлами в одной папке с вложенными пакетными файлами или файлами, в именах которых есть пробелы, посмотрите мое решение ниже. - person Marvin Thobejane; 10.03.2014
comment
Спасибо за шаблон. Я обнаружил, что не могу заключить имя файла в кавычки () - для имен файлов с пробелами просто дает мне имя файла. Например. for /F "tokens=*" %%A in ("myfile.txt") do echo A = %%A - ›A = myfile.txt. Есть идеи, как помешать этому? - person will; 19.04.2016
comment
Убедитесь, что файл, с которым вы работаете, имеет кодировку ANSI или UTF8. Я ломал голову над тем, почему это не работает, пока я не попытался просмотреть файл с помощью команды TYPE, и результат был не таким, как я ожидал. В этот момент я заметил, что файл по какой-то причине был закодирован в UCS-2 BE BOM! - person Dan Stevens; 03.05.2016
comment
Помните, что переменные в пакетном файле должны быть в ВЕРХНЕМ РЕГИСТРЕ, я пытался for /F "tokens=*" %%Region in (RegionsFile.txt) do echo %%Region, и он бросал %Region was unexpected at this time - person Shrikant Prabhu; 14.10.2016
comment
Строки в файле для обработки должны заканчиваться на '\ n', а не только на '\ r'. Мой файл .bat не работал, открыл файл в текстовом редакторе, и все выглядело нормально. Через некоторое время понял, что это не удалось из-за неправильного окончания строки. - person Riga; 06.05.2018
comment
@will Это запоздалый ответ, но в этом случае вам нужно будет использовать usebackq. Например; for /F "usebackq tokens=*" %%A in ("myfile.txt") do echo A = %%A - person Dan; 25.06.2018
comment
@ Дэн ... спасибо, дружище, да, я уже сталкивался с usebackq в прошлом. Вы абсолютно правы в общем случае. Мой вариант использования - просто определить некоторые переменные среды на основе существующей среды set. К счастью, мне не пришлось заходить так далеко. Я рад, что вы напомнили, я оставлю комментарий, когда вернусь, чтобы расширить или клонировать скрипт. - person will; 26.06.2018
comment
@will ... Еще одно замечание. После нескольких опытов с этим шаблоном сценария я решил назвать входной файл source-d, который я читаю, с помощью for /F ... следующим образом: _3 _ расширение для soruce. Таким образом, у меня также может быть xxx.cmd, который запускается с ярлыка: cmd /k xxx.cmd и выполняет соответствующее: xxx.src ... Когда это необходимо. - person will; 26.06.2018
comment
Если вы обнаружите, что этот ответ не работает, проверьте кодировку файла, который вы пытаетесь просмотреть. У меня были проблемы с некоторыми из менее распространенных кодировок. Преобразование в UTF-8 обычно безопасно. - person kayleeFrye_onDeck; 13.11.2018
comment
Стоит отметить, что параметр индекса в вашем цикле должен быть одним символом. Так, например, %% i в порядке, но индекс %% завершится ошибкой. - person Vincent; 06.03.2020
comment
Это не работает для строк в файле, начинающихся с точки с запятой; и пустые строки. - person Zimba; 15.04.2020
comment
Этот ответ требует дополнительных пояснений ... - person Mike Q; 27.05.2021

Из справочника командной строки 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"
person Ash    schedule 01.10.2008
comment
чтобы уточнить использование кавычек, необходимо использовать usebackq: for /f "usebackq" %%a in ("Z:\My Path Contains Spaces\xyz\abc.txt") - person drzaus; 21.02.2014
comment
Почему вы пропустили первый токен? - person Victorio Berra; 14.09.2020

В пакетном файле вы ДОЛЖНЫ использовать %% вместо %: (введите 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 по мере необходимости.

person user332474    schedule 04.05.2010

Улучшение первого ответа «FOR / F ..»: мне нужно было вызвать execute каждый скрипт, указанный в 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
)

Изменить: приведенный выше пример предназначен для выполнения цикла 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---
person Yogesh Mahajan    schedule 23.01.2012

ответ @ MrKraus поучителен. Кроме того, позвольте мне добавить, что если вы хотите загрузить файл, расположенный в том же каталоге, что и пакетный файл, добавьте к имени файла префикс% ~ 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, вам следует сменить каталог на каталог текстового файла. Обратите внимание, что тип по-прежнему требуется для имен файлов с пробелами.

Я надеюсь, что это помогает кому-то!

person Marvin Thobejane    schedule 28.05.2013
comment
Нет необходимости в префиксе имени файла, поскольку командный файл по умолчанию будет искать в текущей папке. - person foxidrive; 28.05.2013
comment
@foxidrive: Хорошо, я тебя слышу. Хотя следует соблюдать осторожность. Например, если каталог был изменен, он будет искать в этом каталоге, а не в том, в котором находится командный файл. Тогда решение будет вызывать **cd /d %~dp0** перед циклом for. Это позволит убедиться, что вы ссылаетесь на файл в каталоге, в котором находится командный файл. Спасибо за наблюдение - person Marvin Thobejane; 18.07.2013
comment
Спасибо и +1 за type обход - person halex; 09.03.2014
comment
Я не могу заставить работать type, мне пришлось указать имя моего файла, потому что оно находится в другом каталоге, содержащем пробелы (Черт побери, Program Files). Я получаю сообщение об ошибке The system cannot find the file `type. - person scragar; 03.07.2014
comment
@scragar, у тебя есть правильная цитата? это должно быть «не а». На моей клавиатуре он находится на той же клавише, что и @. - person FrinkTheBrave; 10.07.2014
comment
@FrinkTheBrave Это была проблема, это обратные кавычки в ответе, поэтому я предположил, что это правильно, спасибо. - person scragar; 10.07.2014
comment
@scragar или вы можете использовать параметр usebackq цикла for. код будет начинаться с for /F "usebackq tokens=*", тогда вы можете использовать обратные кавычки вокруг команды, одинарные кавычки вокруг строк и двойные кавычки вокруг путей к файлам. - person robotik; 06.09.2016
comment
@foxidrive: в Win 10 командный файл по умолчанию не смотрит в текущую папку. Вместо этого он смотрит на папку, зарегистрированную в Win Registry. По умолчанию - пользователь homedir. - person Zimba; 15.04.2020

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

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

@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, но, похоже, нет никакого способа преодолеть это.

person jeb    schedule 18.07.2013
comment
Win 10 не разрешает setlocal в командной строке. Когда я запускаю код в CMD, я получаю! Var! вместо заготовок. Как исправить? - person Zimba; 15.04.2020
comment
Ограничение длины строки можно преодолеть, разделив файл на временные файлы с максимальной длиной строки 8190 перед обработкой. Потом перекомпоновал в один файл. - person Zimba; 15.04.2020

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

FOR /F %%i IN (myfile.txt) DO ECHO %%i
person Paul    schedule 12.08.2009
comment
Два знака процента рядом друг с другом %% рассматриваются как один знак процента в команде (а не в пакетном файле). - person Paul; 24.02.2018

Вот файл 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
person Community    schedule 01.10.2008

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

person Michael Ratanapintha    schedule 01.10.2008

Принятый ответ, использующий 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)

person mivk    schedule 14.10.2018

Модифицированные примеры здесь, чтобы перечислить наши приложения Rails на Heroku - спасибо!

cmd /C "heroku list > heroku_apps.txt"
find /v "=" heroku_apps.txt | find /v ".TXT" | findstr /r /v /c:"^$" > heroku_apps_list.txt
for /F "tokens=1" %%i in (heroku_apps_list.txt) do heroku run bundle show rails --app %%i

Полный код здесь.

person DotDotJames    schedule 11.01.2013
comment
Согласно комментарию к другому вопросу выше - вы можете пропустить создание файла / чтение и просто использовать for /f "tokens=1" %%i in ('find /v "=" heroku_apps.txt ^| find /v ".TXT" ^| findstr /r /v /c:"^$"') do... (обратите внимание на добавление ^, используемых для выхода из канала, так что он передается в for, а не напрямую в командный процессор) - person user66001; 03.02.2013

Чтобы распечатать все строки текстового файла из командной строки (с delayedExpansion):

set input="path/to/file.txt"

for /f "tokens=* delims=[" %i in ('type "%input%" ^| find /v /n ""') do (
set a=%i
set a=!a:*]=]!
echo:!a:~1!)

Работает с ведущими пробелами, пустыми строками, пробельными строками.

Проверено на Win 10 CMD

Тестовый текст

person Zimba    schedule 02.02.2020
comment
Боже попробуйте, но ваш первый образец удаляет ведущий ]]] из строк, второй образец отбрасывает пустые строки и строки, начинающиеся с пробела - person jeb; 02.02.2020
comment
Второй предназначен для удаления пустых строк. 1-й может изменить delims, если какие-либо строки в текстовом файле начинаются с ], например. заменить на какой-либо символ, которого нет, или на управляющий символ, например backspace или колокольчик; они обычно не встречаются в текстовых файлах. Причина delims=] - удалить заполнители, созданные командой /n из find, чтобы сохранить пустые строки. - person Zimba; 02.02.2020
comment
@jeb: скобка]]] проблема исправлена. См. Обновление, чтобы напечатать все строки в текстовом файле. Работает и на Win 10 CMD. - person Zimba; 15.04.2020
comment
Но теперь не получается с восклицательными знаками в тексте, например This bang ! disappears. Кстати, delim=[ вам не нужен, потому что set a=!a:*]=]! тоже удалил бы его, а echo:!a:~1! не требуется, вы можете заменить замену на set a=!a:*]=! - person jeb; 06.10.2020
comment
@jeb: Только что проверил, работает даже с восклицаниями. См. Снимок в разделе "Правка". Вы отложили расширение? Идея delim=[ заключалась в том, чтобы сохранить строки только с пробелами, которые должны быть удалены с помощью set a=!a:*]=]!, поскольку они не являются частью содержимого. Причина set a=!a:*]=]!: set a=!a:*]=! не работает при первоначальном тестировании. Оба работают теперь в окончательном коде с правильным форматом echo. - person Zimba; 06.10.2020
comment
Вы правы, моя тестовая строка работает в командной строке (это было слишком просто), но все эти новые не работают The caret ^ is removed, but the bang ! stays, Use !cd! or %cd% и \..\..\..\windows\system32\calc.exe - person jeb; 07.10.2020
comment
Строка calc.exe у меня работает нормально. Строки каретки и cd могут быть исправлены с помощью подстановки ", ^ & (в моем случае), но, как и в других реализациях CMD, потребуется специализированное решение для ОС, на которой он работает. Кстати, проблема !cd! распространяется на любую допустимую переменную, например. %windir% или !windir!. - person Zimba; 07.10.2020
comment
Ошибка calc.exe зависит от вашего каталога Windows и от того, в каком каталоге вы запускаете код (тот же диск и глубина каталога), но ее можно легко решить с помощью echo(!var!. Остальные проблемы решить нетривиально, так как это поведение отложенного расширения. - person jeb; 07.10.2020
comment
Строка calc.exe у меня работает нормально, это не ошибка. Строки каретки и cd, которые я исправил с помощью замены ^ &, могут не работать для всех разновидностей CMD. - person Zimba; 08.10.2020