2016-05-24 5 views
7

Angenommen wir den folgenden Code-Schnipsel mit einer Textdatei haben sample.txt umgeleitet in STDIN:Warum verarbeiten einige Befehle Zeilen umgeleiteter STDIN-Daten, die bereits von anderen Befehlen verwendet werden?

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

... und der Inhalt der zugehörigen Textdatei sample.txt:

first 
second 
third 
fourth 

Die Ausgabe auf dem zurück Konsole wird dies sein, was genau das ist, was ich erwarte (Zeilen first und second werden von set /P verbraucht, daher findstr empfängt und verarbeitet die restlichen Zeilen):

third 
fourth 
first, second 

die gleiche Leistung erreicht wird, wenn durch findstr /R "^"sort /R ersetzt wird.

Wenn jedoch die findstr Befehlszeilen von find /V "" oder durch more ersetzt, wird der Ausgang sein:

first 
second 
third 
fourth 
first, second 

Es scheint, dass, obwohl set /P bereits die Linien first und second verbraucht, die durch bewiesen die letzte Ausgabezeile, find und auch more erhalten immer noch die gesamten umgeleiteten Daten.

Warum ist das, was verursacht dieses Verhalten? Gibt es eine Möglichkeit, find oder more zu zwingen, nur die verbleibenden umgeleiteten Daten zu empfangen, die noch nicht von einem vorhergehenden Befehl verarbeitet wurden?

(Das Verhalten ist das gleiche, wenn die Ausgangsdaten STDOUT in eine Textdatei umleiten. Auch wenn eine Befehlszeile ähnlich der oben Loskennzeichen in cmd direkt ausgeführt wird, ändert sich nichts.)

+1

Sie können eine Beschreibung dieses Verhaltens [hier] lesen (http://stackoverflow.com/questions/8844868/what-are-the-undoccumed-features-and-limits-of-the-windows-findstr-comman/28278628 # 28278628), aber die Antwort auf Ihre Frage lautet: "weil solche Befehle auf diese Weise programmiert wurden" – Aacini

+0

Sehr interessant, @Aacini! Ich habe schon vermutet, dass 'find' und' more' den Dateizeiger zurücksetzen, weil ich mit allen genannten Befehlen rumgespielt, gemischt und neu geordnet habe, und habe sogar ein 'for/F' um sie gewickelt (zB:' for/F "delims =" %% L in ('mehr') echo (%% L '), was alles überhaupt nichts änderte.Ich fürchte also, es scheint keine (native) Möglichkeit zu geben, dieses Verhalten zu umgehen. – aschipfl

+1

Sie könnten versuchen, das Ergebnis von 'findstr/R"^"' zu "finden"/V "" oder "more" –

Antwort

1

Warum einige tun Befehle verarbeiten Zeilen von umgeleiteten STDIN-Daten, die bereits von anderen Befehlen verwendet werden?

Da einige Befehle/Programme stdin zurückspulen. Sie können dies versuchen:

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

Ergebnis:

third 
    fourth 
    first, second 

Die more +2 überspringt die ersten beiden Zeilen der Datei.

+0

Mit echo% ONE%,% meinen Sie eigentlich echo% ONE%,% TWO% ', oder? Dies ist ein nettes Workaround für den Code, aber 'more' verarbeitet alle Daten weiter (es empfängt alle Zeilen, es überspringt nur zwei Zeilen von seiner Ausgabe) ... – aschipfl

+0

@aschipfl, ja, es hätte'% sein sollen ZWEI% 'nicht'% ', das habe ich verpasst. Habe gerade die Antwort bearbeitet. Ja, 'more' spult immer noch stdin zurück, um die gesamte Datei zu verarbeiten. Wie auch immer, ich denke, es ist die Antwort auf Ihre Frage, einige Programme verhalten sich nicht wie richtige Filter in einer Pipe-Kette. – jwdonahue