Чтение потока stdin в пакетном файле
Можно ли использовать потоковый поток stdin внутри пакетного файла?
Я хочу, чтобы иметь возможность перенаправлять вывод одной команды в мой пакетный файл process.bat
, чтобы:
C:\>someOtherProgram.exe | process.bat
Моя первая попытка выглядела так:
echo OFF
setlocal
:again
set /p inputLine=""
echo.%inputLine%
if not (%inputLine%)==() goto again
endlocal
:End
Когда я тестирую его с помощью type testFile.txt | process.bat
, он несколько раз печатает первую строку.
Есть ли другой способ?
Ответы
Ответ 1
set /p
не работает с каналами, он берет одну (случайную) строку из ввода.
Но вы можете использовать more
внутри цикла for.
@echo off
setlocal
for /F "tokens=*" %%a in ('more') do (
echo #%%a
)
Но это не так, если строки начинаются с точки с запятой (так как стандартом FOR-LOOP для eol является ;
).
И он не может читать пустые строки.
Но с помощью findstr вы тоже можете решить эту проблему: в каждой строке добавляется номер белья, поэтому вы никогда не получите пустых строк.
И тогда префикс удаляется до первого двоеточия.
@echo off
setlocal DisableDelayedExpansion
for /F "tokens=*" %%a in ('findstr /n $') do (
set "line=%%a"
setlocal EnableDelayedExpansion
set "line=!line:*:=!"
echo(!line!
endlocal
)
В качестве альтернативы, в некоторых средах (например, WinRE), которые не включают findstr
, альтернативы с find.exe
может быть достаточно. find
примет пустую строку поиска ""
и разрешит инверсию поиска. Это позволило бы что-то вроде этого:
@echo off
setlocal DisableDelayedExpansion
for /F "tokens=*" %%a in ('find /v ""') do (
...
Ответ 2
Синтаксис "line=!line:*:=!
":
-
Для набора
-
требуется один параметр a=b
.
Если a содержит пробел или что-то еще, вам придется использовать кавычки вокруг этого параметра. Здесь я не вижу никаких
-
!line:*:=!
Для этого синтаксиса вы можете ввести 'set /?
', чтобы увидеть официальное описание использования переменных.
!var!
выглядит как %var%
, чтобы получить значение. Но !var!
означает задержанное расширение.
строка var name
первый: знак изменения переменной.
**:= **:=
(пустой), замените строку в значении переменной "*:
" (практически от начала строки до первого :
) с (пустым), то есть удалите подстроку от начала до первой двоеточия.
Ответ 3
FOR /F "tokens=1* delims=]" %%A IN ('FIND /N /V ""') DO (
> CON ECHO.%%B
>> %File% ECHO.%%B
)
Источник здесь: http://www.robvanderwoude.com/unixports.php#TEE
Ответ 4
В качестве альтернативы, в некоторых средах (например, WinRE), которые не включают findstr
, альтернативы с find.exe
может быть достаточно. find
будет принимать нулевую строку поиска ""
и разрешает инверсию поиска. Это позволит сделать что-то вроде этого:
@echo off
setlocal DisableDelayedExpansion
for /F "tokens=*" %%a in ('find /v ""') do (
set "line=%%a"
echo(!line!
)