Прочитать поток stdin в командном файле - PullRequest
33 голосов
/ 08 августа 2011

Можно ли использовать поточный поток 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, он несколько раз печатает первую строку.

Есть ли другой способ?

Ответы [ 4 ]

34 голосов
/ 08 августа 2011

set /p не работает с трубами, он занимает одну (случайную) строку от входа.
Но вы можете использовать more внутри цикла for.

@echo off
setlocal
for /F "tokens=*" %%a in ('more') do (
  echo #%%a
)

Но это не получается, если строки начинаются с точки с запятой (так как стандарт eol для FOR-LOOP равен ;).
И он не может читать пустые строки.
Но с помощью 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 (
  set "line=%%a"
  echo(!line!
)
3 голосов
/ 15 августа 2012

Синтаксис "line=!line:*:=!" установлен:

  1. для установки требуется один параметр a=b.
    Если a содержит пробел или что-то, вы должны будете использовать кавычки вокруг этого параметра. Здесь я не вижу никаких

  2. !line:*:=!
    Для этого синтаксиса вы можете набрать 'set /?', чтобы увидеть официальное описание использования переменных.
    !var! похоже на %var%, чтобы получить значение. Но !var! означает задержка расширения .

имя строки var

первый: переменная отметка модификации.

**:= **:= (пусто), заменить строку в совпадении значения переменной "*:" (практически от начала строки до первого : вхождения) на (пусто), т.е. удалить подстроку от начала до первого двоеточия .

1 голос
/ 25 февраля 2016

Кроме того, в некоторых средах (например, WinRE), которые не включают findstr, альтернативы с find.exe может быть достаточно. find примет пустую строку поиска "" и разрешит инверсию поиска. Это позволило бы что-то вроде этого:

@echo off
setlocal DisableDelayedExpansion

for /F "tokens=*" %%a in ('find /v ""') do (
  set "line=%%a"
  echo(!line!
)
1 голос
/ 25 ноября 2014
FOR /F "tokens=1* delims=]" %%A IN ('FIND /N /V ""') DO (
    >  CON    ECHO.%%B
    >> %File% ECHO.%%B
)

Источник здесь: http://www.robvanderwoude.com/unixports.php#TEE

...