Відповіді:
Подані нижче публікації дуже допомогли, але не зробили те, про що я говорив у своєму запитанні, де мені потрібно обробити весь рядок у цілому. Ось що я знайшов працювати.
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
Ключове слово лексеми зірочкою (*) потягне весь текст для всього рядка. Якщо ви не введете зірочку, вона лише виведе перше слово на рядку. Я припускаю, що це стосується пробілів.
Я ціную всі публікації!
Якщо у шляху до файлу є пробіли, вам потрібно скористатися usebackq
. Наприклад.
for /F "usebackq tokens=*" %%A in ("my file.txt") do [process] %%A
for /F "tokens=*" %%A in ("myfile.txt") do echo A = %%A
-> A = myfile.txt
. Будь-які ідеї, як перешкодити цьому?
З посилання на командний рядок 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"
У пакетному файлі ви ОБОВ'ЯЗКОВО використовувати %%
замість %
: (Тип 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
Що це робить: "виконувати виклик: процес %% i %% j %% k" наприкінці команди for передає інформацію, отриману в команді for, з myfile.txt в "підпрограму" "процес".
Коли ви використовуєте команду for у пакетній програмі, вам потрібно використовувати подвійні знаки% для змінних.
Наступні рядки передають ці змінні від команди for до «підпрограми» процесу і дозволяють обробляти цю інформацію.
set VAR1=%1
set VAR2=%2
set VAR3=%3
У мене є досить розвинене використання цієї точної установки, з якою я б хотів поділитися, якщо потрібні додаткові приклади. Додайте, звичайно, свій EOL або Delims.
Удосконалення першої відповіді "FOR / F ..": Що мені довелося зробити, це викликати виконання кожного сценарію, перерахованого в 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---
@ MrKraus в відповідь повчально. Далі дозвольте додати, що якщо ви хочете завантажити файл, розташований у тому самому каталозі, як і пакетний файл, префікс імені файлу% ~ dp0. Ось приклад:
cd /d %~dp0
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
Примітка.: Якщо у вашому файлі або каталозі (наприклад, myfile.txt у наведеному вище прикладі) є пробіл (наприклад, "мій файл.txt" або "c: \ програмні файли"), використовуйте:
for /F "tokens=*" %%A in ('type "my file.txt"') do [process] %%A
, із ключовим словом типу, що викликає type
програму, яка відображає вміст текстового файлу. Якщо ви не хочете зазнавати накладних витрат на виклик команди type, слід змінити каталог у каталог текстового файлу. Зауважте, що тип усе ще потрібен для імен файлів з пробілами.
Я сподіваюся, що це комусь допоможе!
**cd /d %~dp0**
цикл for. Це переконається, що ви посилаєтесь на файл у каталозі, в якому знаходиться пакетний файл. Дякую за спостереження
type
обходу
type
обійти роботу, мені довелося процитувати своє ім'я файлу, оскільки воно знаходиться в іншому каталозі, який містить пробіли (Чорт ти Program Files
). Я отримую помилкуThe system cannot find the file `type.
Прийнята відповідь хороша, але має два обмеження.
У неї випадають порожні рядки та рядки, починаючи з;
Щоб читати рядки будь-якого вмісту, вам потрібна техніка перемикання розширення.
@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 використовується для префіксації кожного рядка з номером рядка та двокрапкою, тому порожні рядки більше не порожні.
Відкладене розширення потрібно вимкнути, коли отримувати доступ до %%a
параметра, інакше знаки оклику !
та піклування ^
будуть втрачені, оскільки в цьому режимі вони мають особливі значення.
Але для видалення номера рядка з нього потрібно включити затримку розширення.
set "var=!var:*:=!"
видаляє всі до першої кишки (використання delims=:
видалить також усі двокрапки на початку рядка, не тільки ту, що знаходиться з findstr).
Endlocal знову відключає затримку розширення для наступного рядка.
Єдине обмеження - це обмеження довжини лінії ~ 8191, але, здається, немає способу подолати це.
setlocal
в командному рядку. Коли я запускаю код на CMD, я отримую! Var! замість заготовок. Як виправити?
Ось файл 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
Якщо у вас є NT-сімейства Windows (один з в cmd.exe
якості оболонки), спробуйте команду FOR / F .
Прийнятий відгук, що використовує 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 )
Тут можна змінити приклади, щоб перелічити наші програми 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
Повний код тут .
for /f "tokens=1" %%i in ('find /v "=" heroku_apps.txt ^| find /v ".TXT" ^| findstr /r /v /c:"^$"') do...
(Зверніть увагу на додавання ^
, яке використовується для втечі з труби, щоб воно було передане for
командному процесору, а не безпосередньо)
Щоб надрукувати всі рядки в текстовому файлі з командного рядка (із затримкою розширення):
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
]]]
з ліній, другий зразок краплі порожні рядки і рядки , що починаються з простором
delims
якщо будь-які рядки в текстовому файлі починаються з ]
напр. замінити на якийсь символ, який не має, або керуючий символ на зразок зворотної області чи дзвоника; вони зазвичай не знаходяться в текстових файлах. Причина delims=]
полягає у видаленні наповнювачів , створені /n
з find
команди , щоб зберегти порожні рядки.
%%A
з%A
в команді вище. Інакше ви отримаєте%%A was unexpected at this time.
.