2011-08-08 12 views
28

¿Es posible utilizar un flujo de entrada estándar entubada dentro de un archivo por lotes?corriente entrada estándar en un archivo por lotes

Quiero ser capaz de redirigir la salida de un comando en mi archivo por lotes process.bat lista para:

C:\>someOtherProgram.exe | process.bat 

Mi primer intento parecía:

echo OFF 
setlocal 

:again 
set /p inputLine="" 
echo.%inputLine% 
if not (%inputLine%)==() goto again 

endlocal 
:End 

Cuando la prueba con type testFile.txt | process.bat imprime la primera línea repetidamente.

¿Hay otra manera?

+2

¡Gran pregunta, buena respuesta, realmente mal que no hay una mejor respuesta! –

Respuesta

31

set /p no funciona con tubos, se necesita una línea (al azar) de la entrada.
Pero puede usar more dentro de un bucle for.

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

Pero esto no funciona con líneas que comienzan con un punto y coma (como el bucle-FOR-estándar de EOL es ;).
Y no puede leer las líneas vacías.
Pero con findstr puede resolver esto también, se Prefijo en cada línea con el LineNumber, por lo que nunca obtener líneas vacías.
Y luego el prefijo se elimina a los primeros dos puntos.

@echo off 
setlocal DisableDelayedExpansion 

for /F "tokens=*" %%a in ('findstr /n $') do (
    set "line=%%a" 
    setlocal EnableDelayedExpansion 
    set "line=!line:*:=!" 
    echo(!line! 
    endlocal 
) 

alternativa, en algunos entornos (como WinRE) que no incluyen findstr, una alternativa con find.exe puede ser suficiente. find aceptará una cadena de búsqueda nula "", y permite la inversión de búsqueda. Esto permitiría que algo como esto:

@echo off 
setlocal DisableDelayedExpansion 

for /F "tokens=*" %%a in ('find /v ""') do (
    set "line=%%a" 
    echo(!line! 
) 
+1

Esto parece funcionar. No he visto la sintaxis 'set" line =! Line: *: =! "' Antes. Más locura de script por lotes. Lo he adaptado ligeramente para usar las herramientas MSYS; 'sed" s/^ \ (. * \) $/\ "\ 1 \"/"'' en lugar de 'findstr/n $'. El cuerpo puede ser reemplazado con 'echo. %% ~ a' y puede manejar ninguno de dos finales de línea (que tengo en muchos archivos). – m0tive

+5

Es mejor usar 'FINDSTR/N"^"'. Esa búsqueda devolverá correctamente todas las líneas, incluidas las líneas formateadas con unix, así como cualquier línea final que no termine con una nueva línea. – dbenham

+0

Creo que puede usar 'for/F" tokens = * eol = "' para tratar con líneas que comiencen con punto y coma. – wangzq

3

El conjunto "line=!line:*:=!" sintaxis es:

  1. conjunto requiere un parámetro que es a=b.
    Si contiene un espacio o algo así, deberá usar las comillas alrededor de este parámetro. Aquí no veo ninguna

  2. !line:*:=!
    Por esta sintaxis, puede escribir 'set /?' para ver la descripción oficial sobre el uso de las variables.
    !var! es como %var%, para obtener el valor. Pero !var! significa expansión retardada.

nombre de la línea var

la primera: Variable de marca de modificación.

**:= **:= (vacío), vuelva a colocar la cadena en partidos valor de la variable "*:" (prácticamente de la cadena comenzará a primera ocurrencia :) con (vacío), es decir, eliminar la subcadena desde el principio hasta el primero de colon.

1
FOR /F "tokens=1* delims=]" %%A IN ('FIND /N /V ""') DO (
    > CON ECHO.%%B 
    >> %File% ECHO.%%B 
) 

Fuente aquí: http://www.robvanderwoude.com/unixports.php#TEE

+0

Esto no falla en las líneas que comienzan con un punto y coma. – Ben

+0

Pero para mí, falló en las líneas que comienzan con ']'. –

1

alternativa, en algunos entornos (como WinRE) que no incluyen findstr, una alternativa con find.exe podría ser suficiente. find aceptará una cadena de búsqueda nula "", y permite la inversión de búsqueda. Esto permitiría algo como esto:

@echo off 
setlocal DisableDelayedExpansion 

for /F "tokens=*" %%a in ('find /v ""') do (
    set "line=%%a" 
    echo(!line! 
) 
Cuestiones relacionadas