Ausgezeichnete und interessante Frage (+1)
Der Abstand wird durch den Pipe-Mechanismus des CMD-Parsers eingeführt, nicht durch SORT.
Wenn Sie ein Befehl mit FOR /F ausführen, wird der Befehl in seiner eigenen CMD-Shell ausgeführt. Außerdem wird jede Seite einer Pipe in ihrer eigenen CMD-Shell ausgeführt. Siehe Warum schlägt die verzögerte Erweiterung fehl, wenn sie sich innerhalb eines gepipeten Codeblocks befindet? für weitere Informationen.
Ihr Befehl instanziiert also tatsächlich 3 CMD-Shells, einen für den FOR /F-Befehl, der wiederum 2 für jede Seite der Pipe erstellt.
Sie können sehen, wie die Befehle analysiert und in die CMD-Shell mithilfe der dynamischen Variable %CMDCMDLINE% eingegeben werden. Da wir den Befehl von der Befehlszeile ausführen, müssen wir mindestens ein Zeichen im Variablennamen zweimal escapen, damit es nicht expandiert wird, bis es die innerste CMD-Shell erreicht.
Hier ist der Befehl mit den Ergebnissen (das führende >
ist meine Eingabeaufforderung):
>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
Die letzte Ausgabezeile ist die Befehlszeile, die für die linke Seite der Pipe verwendet wurde. Sie können sehen, wie der Parser an mehreren Stellen Leerzeichen hinzugefügt hat.
Sie können das Problem umgehen, indem Sie ein einfaches Stapelskript verwenden, um den Wert zu echoen, anstelle des ECHO-Befehls.
echoArgs.bat
@echo(%*
Wenn Sie diesen Befehl jetzt ausführen, erhalten Sie das gewünschte Ergebnis
>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
Eine weitere Methode, um das Problem zu umgehen, besteht darin, eine Variable mit Ihrem ECHO-Befehl zu erstellen und die Expansion der Variable entsprechend zu escapen.
>set cmd=@(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
BEARBEITEN
Das >_tempfile echo and here's a space|more
Beispiel ist auch interessant. Am Ende der Ausgabedatei befindet sich ein zusätzliches Leerzeichen. Aber Chad Nouis hat recht, dass nichts sortiert wird, aufgrund der Umleitung auf der linken Seite. Jeder Befehl könnte auf der rechten Seite verwendet werden und das Ergebnis wäre dasselbe.
Die Ursache des Problems ist immer noch der Parser, aber die Art und Weise, wie der Parser den Befehl umstrukturiert, ist interessant.
>>_tempfile echo %^cmdcmdline%|rem
>type _tempfile
C:\Windows\system32\cmd.exe /S /D /c" echo %cmdcmdline% 1>_tempfile"
Beachten Sie, wie die Umleitung vom Anfang zum Ende des Befehls verschoben wird und der Dateigriff von 1
explizit hinzugefügt wird. Sie können sicherlich sehen, wo das zusätzliche Leerzeichen herkommt.