2016-05-24 27 views
7

Przypuśćmy mamy następujący fragment kodu z pliku tekstowego sample.txt, które zostało przekształcone pod STDIN:Dlaczego niektóre polecenia przetwarzają linie przekierowanych danych STDIN, które są już zużywane przez inne polecenia?

@echo off 
< "sample.txt" (
    set /P "ONE=" 
    set /P "TWO=" 
    findstr /R "^" 
) 
echo %ONE%, %TWO% 

... i zawartość pliku tekstowego związanego sample.txt:

first 
second 
third 
fourth 

Wyjście zwrócone na będzie to konsola, której dokładnie oczekuję (linie first i second są zużywane przez set /P, stąd findstr odbiera i przetwarza pozostałe linie):

third 
fourth 
first, second 

samo wyjście osiąga się findstr /R "^" otrzymuje sort /R.

Jednak przy wymianie wiersza poleceń findstr przez find /V "" lub more, wyjście będzie:

first 
second 
third 
fourth 
first, second 

Wydaje się, że chociaż set /P już zużyte przewody first i second o czym świadczą ostatnia linia wyjściowa, find, a także more nadal otrzymują całe przekierowane dane.

Dlaczego to jest przyczyną tego zachowania? Czy istnieje sposób na wymuszenie, aby find lub more otrzymywać tylko pozostałe przekierowane dane, które nie zostały wcześniej przetworzone przez poprzednie polecenie?

(zachowanie jest takie samo, gdy przekierowanie danych wyjściowych STDOUT do pliku tekstowego. Również przy wykonywaniu wiersza polecenia podobny do powyższego kodu wsadowego w cmd bezpośrednio, nic się nie zmienia.)

+1

Możesz przeczytać opis tego zachowania [tutaj] (http://stackoverflow.com/questions/8844868/what-are-the-undocumented-features-and-limitations-of-t--windows-findstr-comman/28278628 # 28278628), ale odpowiedź na twoje pytanie brzmi: "ponieważ takie polecenia zostały zaprogramowane w ten sposób" – Aacini

+0

Bardzo interesujące, @Aacini! Podejrzewałem już, że 'find' i' more' resetują wskaźnik pliku, ponieważ grałem z wszystkimi poleceniami, o których wspomniałem, mieszałem je i zmieniałem je, a nawet owinąłem 'for/F' wokół nich (jak:' for/F "delims =" %% L in ('more') to echo (%% L'), które nic nie zmieniło.Tak więc obawiam się, że wydaje się, że nie ma (natywnego) sposobu na obejście tego zachowania? – aschipfl

+1

Możesz spróbować potokować wynik 'findstr/R"^"' do 'find/V" "' lub 'more' –

Odpowiedz

1

Dlaczego niektóre komendy przetwarzają linie przekierowanych danych STDIN, które są już zużywane przez inne polecenia?

Ponieważ niektóre polecenia/programy przewijają stdin. Można spróbować to:

@echo off 
< "sample.txt" (
    set /P "ONE=" 
    set /P "TWO=" 
    more +2 
) 
echo %ONE%, %TWO% 

Wynik:

third 
    fourth 
    first, second 

more +2 pomija pierwsze dwie linijki pliku.

+0

Przez 'echo% ONE%,%', masz na myśli 'echo% ONE%,% TWO%', prawda? To dobra praca dla kodu pod ręką, ale 'more' nadal przetwarza wszystkie dane (odbiera wszystkie linie, po prostu pomija dwie linie od wyjścia) ... – aschipfl

+0

@aschipfl, tak powinno być'% DWIE% "nie"% ", tęskniłem za tym. Właśnie zredagowałem odpowiedź. Tak, 'more' nadal przewija stdin, aby przetworzyć cały plik. W każdym razie, myślę, że to jest odpowiedź na twoje pytanie, niektóre programy nie zachowują się jak właściwe filtry w łańcuchu rur. – jwdonahue