excelente e interesante pregunta (+1)
El espacio se introduce por el mecanismo de la tubería del analizador CMD, no por género.
Cuando ejecuta un comando usando FOR/F, el comando se ejecuta en su propio shell CMD. Además, cada lado de una tubería se ejecuta en su propio shell CMD. Ver Why does delayed expansion fail when inside a piped block of code? para más información.
De modo que su comando realmente ejemplifica 3 shells CMD, uno para el comando FOR/F, que a su vez crea 2 para cada lado de la tubería.
Puede ver cómo los comandos se analizan y alimentan en el shell de CMD utilizando la variable dinámica% CMDCMDLINE%. Debido a que estamos ejecutando el comando desde la línea de comando, necesitamos escapar al menos un carácter en el nombre de la variable dos veces para que no se expanda hasta que llegue al caparazón CMD más interno.
Este es el comando con los resultados (el principal >
es mi símbolo del sistema):
>for /f "delims=" %a in ('(echo %^^^cmdcmdline%^&for /l %z in (1,1,10^) do @echo %z^)^|sort') do @echo %a0
1 0
10 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
C:\Windows\system32\cmd.exe /S /D /c" (echo %cmdcmdline% & FOR /L %z in (1 1 10) do @ echo %z)" 0
La última línea de salida es la línea de comandos que se utiliza para el lado izquierdo de la tubería. Puede ver cómo el analizador agregó espacios en varios lugares.
Puede evitar el problema mediante el uso de un simple script por lotes para repetir el valor en lugar del comando ECHO.
echoArgs.bat
@echo(%*
Ahora cuando se ejecuta este comando se obtiene el resultado deseado
>for /f "delims=" %a in ('(for /l %z in (1,1,10^) do @echoArgs %z^)^|sort') do @echo %a0
10
100
20
30
40
50
60
70
80
90
Otro método para evitar el problema es crear una variable con el comando ECHO y escapar de la expansión de la variable apropiadamente.
>set [email protected](echo %z)
>for /f "delims=" %a in ('(for /l %z in (1,1,10^) do %^^^cmd%^)^|sort') do @echo %a0
10
100
20
30
40
50
60
70
80
90
EDITAR
El ejemplo >_tempfile echo and here's a space|more
es también interesante. Hay un espacio extra al final del archivo de salida. Pero Chad Nouis tiene razón en que no se está solucionando nada debido a la redirección del lado izquierdo. Cualquier comando podría usarse en el lado derecho y el resultado sería el mismo.
El origen del problema sigue siendo el analizador sintáctico, pero la forma en que el analizador reestructura la comunicación es interesante.
>>_tempfile echo %^cmdcmdline%|rem
>type _tempfile
C:\Windows\system32\cmd.exe /S /D /c" echo %cmdcmdline% 1>_tempfile"
Aviso cómo el cambio de dirección se mueve desde el principio hasta el final del comando, y se añade explícitamente el identificador de archivo de 1
. Desde luego, puedes ver de dónde viene el espacio extra.
Ah, eso que aumenta el conocimiento, aumenta la pena_. Nunca pensé que la tubería fuera más que una conexión stdin/stdout. Aceptó su respuesta para una explicación pero no para la solución. Aquí está el sencillo: 'for/f" delims = "% a in ('cmd/c" para/l% z in (1,1,10) do @echo% z "^ | sort') do @echo% a0' –
@ panda-34 - Esa ciertamente es otra solución. – dbenham
+1, soy demasiado tarde, me gusta este tipo de preguntas, pero ya las respondió con su buen análisis – jeb