Doskonała i interesujące pytanie (+1)
przestrzeń jest wprowadzany przez mechanizm rury parsera CMD, a nie przez sortowanie.
Po uruchomieniu polecenia za pomocą FOR/F polecenie jest wykonywane we własnej powłoce CMD. Ponadto każda strona rury jest wykonywana we własnej powłoce CMD. Aby uzyskać więcej informacji, patrz Why does delayed expansion fail when inside a piped block of code?.
Twoja komenda faktycznie tworzy 3 powłoki CMD, jedną dla polecenia FOR/F, która z kolei tworzy po 2 dla każdej strony rury.
Możesz zobaczyć, jak polecenia są analizowane i podawane do powłoki CMD przy użyciu zmiennej dynamicznej% CMDCMDLINE%. Ponieważ wykonujemy polecenie z wiersza poleceń, musimy dwukrotnie wymazać co najmniej jeden znak w nazwie zmiennej, aby nie był rozwijany, dopóki nie dotrze do najbardziej wewnętrznej powłoki CMD.
Oto komenda z wynikami (wiodący >
jest mój wiersz poleceń):
>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
Ostatni wiersz wyjścia jest linia poleceń używany do lewej strony rury. Możesz zobaczyć, w jaki sposób parser dodał spacje w wielu miejscach.
Można ominąć problem za pomocą prostego skryptu wsadowego, aby wywołać echo wartości zamiast polecenia ECHO.
echoArgs.bat
@echo(%*
Teraz po uruchomieniu tej komendy można uzyskać Inną metodą pożądanego rezultatu
>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
celu obejścia tego problemu jest utworzenie zmiennej z polecenia ECHO i uciec odpowiednio przed ekspansją zmiennej.
>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
EDIT
Przykład >_tempfile echo and here's a space|more
jest interesujące. Na końcu pliku wyjściowego znajduje się dodatkowe miejsce. Ale Chad Nouis ma rację, że nic nie jest sortowane z powodu przekierowania lewej strony. Każde polecenie może być użyte po prawej stronie, a wynik będzie taki sam.
Źródłem problemu jest nadal parser, ale sposób, w jaki parser restrukturyzuje komunikat, jest interesujący.
>>_tempfile echo %^cmdcmdline%|rem
>type _tempfile
C:\Windows\system32\cmd.exe /S /D /c" echo %cmdcmdline% 1>_tempfile"
Wskazówki jak przekierowanie jest przesuwany od początku do końca polecenia, a uchwyt pliku 1
wyraźnie dodał. Z pewnością możesz zobaczyć, skąd pochodzi dodatkowa przestrzeń.
Ach, to, co zwiększa wiedzę, zwiększa ból. Nigdy nie myślałem o potoku jako o więcej niż połączenie stdin/stdout. Zaakceptowano odpowiedź na wyjaśnienia, ale nie na rozwiązanie. Oto prosty: 'dla/f" delims = "% a w (" cmd/c "dla/l% z w (1,1,10) do @echo% z"^| sort ") do @echo% a0' –
@ panda-34 - To z pewnością jest inne rozwiązanie. – dbenham
+1, Spóźniłem się, lubię tego typu pytania, ale odpowiedziałeś już na to z dobrą analizą – jeb