Mit bash möchte ich oft die Überschriften einer großen CSV-Datei erhalten und den Rest nach einem bestimmten Eintrag durchsuchen. Ich mache das wie folgt.
%Vor%Aber die Eingabe von cat oder einem anderen Befehl funktioniert nicht - es scheint, dass grep niemals den Rest der Datei passiert.
%Vor%Warum gibt es in diesen beiden Fällen ein unterschiedliches Verhalten?
Der Unterschied zwischen dem Lesen aus einer Pipe und dem Lesen aus einer Datei besteht darin, dass Sie lseek
für eine Datei, aber nicht für eine Pipe verwenden können.
Das Verhalten hier sieht (wie durch strace
gesehen) aus, als käme es von head
, nicht bash. head
liest einen Puffer und findet die entsprechende Anzahl von Zeilen, dann lseek
rückwärts bis zu dem Punkt, an dem die Zeile mit der letzten Ausgabe endete, wobei das Datei-Handle an dieser Stelle offen bleibt. Wie oben funktioniert das, wenn es eine Datei liest, aber nicht, wenn es von einer Pipe liest.
Ich kann mir keinen Fall vorstellen anderen als das, was Sie tun, wo dieses Verhalten in head
sinnvoll ist, aber da ist es. Lerne jeden Tag etwas Neues, ich sage dir ...
Ich kann das mit bash 3.2.48 nicht zuverlässig reproduzieren. Beide sind erfolgreich oder beide Fehler. Der Grund für die Fehler ist jedoch, wie groß die Datei ist.
cat
liest einen Puffer (4k-64k je nach System) und gibt es in die Pipe. head
verbraucht den gesamten Puffer und endet dann. grep
hat dann Zugriff auf die Datei nach der Puffergröße. Auf meinem System kann ich deine Pipe nur zu grep
thing weiter als einen Puffer in die Datei einfügen (so kann ich grep
sachen am Ende einer langen Datei, aber nicht am Anfang nach der Verwendung von head
).
Es ist möglich, dass spätere Versionen von bash den Operator <
optimieren (aber nicht cat
), damit Ihr Trick funktioniert, aber ich glaube nicht, dass dies ein unterstütztes Verhalten ist.