Wann sollte ich die Eingabeumleitung verwenden?

21

Ich habe die folgenden zwei Befehle verwendet, um die gleichen Ergebnisse zu erzielen:

[root@localhost ~]# grep line comments
The line should start with a single quote to comment in VB scripting.
Double slashes in the beginning of the line for single line comment in C.
[root@localhost ~]#

[root@localhost ~]# grep line <comments
The line should start with a single quote to comment in VB scripting.
Double slashes in the beginning of the line for single line comment in C.
[root@localhost ~]#

Könnten Sie mir bitte die Vor- und Nachteile erläutern, wenn sich diese beiden Ansätze überschneiden?

Ankit
quelle

Antworten:

28

Von der man grepSeite (auf Debian):

BESCHREIBUNG

   grep  searches the named input FILEs (or standard input if no files are
   named, or if a single hyphen-minus (-) is given as file name) for lines
   containing  a  match to the given PATTERN.  By default, grep prints the
   matching lines.

Im ersten Fall wird grepdie Datei geöffnet. in der zweiten, öffnet sich die Schale die Datei und weist sie der Standardeingabe grepund grepkeine Dateinamenargument übergeben wird davon ausgegangen , es seine Standardeingabe grep muss.

Vorteile von 1:

  • grep kann mehr als eine Datei erfassen¹.
  • grepkann den Dateinamen anzeigen, in dem jedes Vorkommen von linegefunden wird.

Vorteile von 2:

  • Wenn die Datei nicht geöffnet werden kann, gibt die Shell einen Fehler zurück, der relevantere Informationen (wie die Zeilennummer im Skript) und konsistenter enthält (wenn Sie die Shell Dateien auch für andere Befehle öffnen lassen) als wenn grepöffnet es. Und wenn die Datei nicht geöffnet werden kann, grepwird sie nicht einmal aufgerufen (was bei manchen Befehlen - vielleicht auch nicht grep- einen großen Unterschied machen kann).
  • in grep line < in > out, wenn innicht geöffnet werden kann, outwird nicht erstellt oder abgeschnitten.
  • Es gibt kein Problem mit einigen Dateien mit ungewöhnlichen Namen (wie -oder Dateinamen beginnend mit -) ².
  • Kosmetik: Sie können <filedie Befehlszeile an einer beliebigen Stelle platzieren, um den Befehlsfluss natürlicher darzustellen, wie <in grep line >outSie es vorziehen.
  • Kosmetik: Mit GNU grepkönnen Sie auswählen, welches Label vor der passenden Zeile verwendet werden soll, anstatt nur den Dateinamen wie in:

    <file grep --label='Found in file at line' -Hn line
    

In Bezug auf die Leistung, wenn die Datei nicht geöffnet werden kann, speichern Sie die Ausführung grepbei Verwendung der Umleitung, aber ansonsten greperwarte ich keinen großen Unterschied.

Mit der Umleitung sparen Sie sich die Übergabe eines zusätzlichen Arguments, grepund das grepParsen der Argumente wird etwas einfacher. Andererseits benötigt die Shell (mindestens) einen zusätzlichen Systemaufruf zum dup2()Dateideskriptor auf Dateideskriptor 0.

In { grep -m1 line; next command; } < file, grep(hier GNU grep) werden will , seek()um direkt nach der Übereinstimmungslinie zurück , so dass die next commandden Rest der Datei sieht (es wird auch brauchen , um zu bestimmen , ob die Datei durchsuchbar ist oder nicht). Mit anderen Worten, die Position innerhalb von stdin ist eine weitere grepAusgabe von stdin . Mit grep -m1 line file, es kann das optimieren, das ist eine Sache weniger, um die grepman sich kümmern muss.


Anmerkungen

¹ Mit zshkönnen Sie Folgendes tun:

grep line < file1 < file2

Dies entspricht jedoch cat file1 file2 | grep line(ohne das catDienstprogramm aufzurufen ) und ist daher weniger effizient. Dies kann zu Verwirrung führen, wenn die erste Datei nicht mit einem Zeilenumbruch endet und Sie nicht wissen lassen, in welcher Datei das Muster gefunden wird.

² Im Fall von ksh93und bashobwohl gibt es Dateien wie /dev/tcp/host/port(und /dev/fd/xauf einigen Systemen in bash), bei denen die Shell bei Verwendung als Umleitungsziel für spezielle Zwecke abfängt, anstatt die Datei wirklich auf dem Dateisystem zu öffnen (obwohl im Allgemeinen diese Dateien) existiert nicht im Dateisystem). /dev/stdinDies hat den gleichen Zweck wie der -, der von erkannt wurde grep, aber zumindest ist der Namespace hier korrekter (jeder kann eine Datei erstellen, die -in einem beliebigen Verzeichnis aufgerufen wird , während nur Administratoren eine Datei erstellen können, die aufgerufen wird, /dev/tcp/host/portund Administratoren sollten es besser wissen).

Stéphane Chazelas
quelle
+1, für die nette Erklärung. Ich habe einen Zweifel: im 2. Fall, wenn die Shell die Datei öffnet, gibt sie den Inhalt der geöffneten Datei an die Standardeingabe (Tastatur) weiter? (Ich wurde mit dem Begriff 'Standardeingabe von grep' verwechselt).
Ankit
1
Bei @Ankit, stdin lesen Anwendungen standardmäßig ihre Eingabe, den Dateideskriptor 0. In einem Terminal wird fd 0 durch Lesen auf dem Terminalgerät geöffnet (so etwas wie / dev / ttyxx oder / dev / pts / n). Auf diese Weise erhalten sie das, was Sie auf der Tastatur eingeben. Die Shell-Umleitung der Standard-ID eines Befehls öffnet lediglich die Datei fd 0 in einer anderen Datei, bevor der Befehl ausgeführt wird.
Stéphane Chazelas
6

Die Antwort von StephaneChazelas deckt ab grep(1), und die meisten Befehle der Unix-Linie funktionieren auf diese Weise, aber nicht alle. Es ist Standard, entweder von der Standardeingabe (von der Tastatur, von einer über umgeleiteten Datei < fileoder von der durch einen anderen Befehl weitergeleiteten Ausgabe, dummes Beispiel ls * | grep '^ab*c$') oder von der (den) Datei (en) zu lesen, die als Argumente wie angegeben sind grep comment file1 file2 file3. Bei einigen Befehlen wird die Konvention verwendet, dass die genannte Datei die -Standardeingabe ist. Sie können also sagen make-middle | cat head - tail, dass Sie einen Stream headabrufen gen-middlemöchten, unabhängig davon, was generiert wird, gefolgt von tail. Dies ist beabsichtigt, um die Verwendung der Befehle flexibel zu gestalten.

Welches ist besser? Solange es funktioniert, cmd fileist kürzer als cmd < file; Möglicherweise gibt es einen kleinen Zeitunterschied zwischen der Shell, die das Datei-Frobbing ( <) ausführt, und dem Befehl, der es selbst ausführt , aber wahrscheinlich unbemerkt, es sei denn, Sie tun den ganzen Tag nichts anderes. Es wird auf Überlegungen wie die in Stephanes Antwort erwähnten Profis ankommen.

vonbrand
quelle
cmd fileist nicht kürzer als cmd<filewenn.
Stéphane Chazelas
Es ist jedoch nur ein Tastendruck kürzer, vorausgesetzt, Sie müssen die Umschalttaste drücken, um a einzugeben <.
DopeGhoti