Quando devo utilizzare il reindirizzamento dell'input?


21

Ho usato i seguenti due comandi per produrre gli stessi risultati: -

[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 ~]#

Qualcuno potrebbe spiegarmi eventuali vantaggi / svantaggi se uno di questi 2 si avvicina l'uno all'altro.

Risposte:


28

Dalla man greppagina (su Debian):

DESCRIZIONE

   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.

Nel primo caso, grepapre il file; nel secondo, la shell apre il file e lo assegna all'input standard di grep, e grepnon essendo passato alcun argomento sul nome del file presuppone che debba grep il suo input standard.

Pro di 1:

  • grep può grep più di un file¹.
  • greppuò visualizzare il nome del file in cui si trova ogni occorrenza di line.

Pro di 2:

  • Se il file non può essere aperto, la shell restituisce un errore che includerà informazioni più rilevanti (come il numero di riga nello script) e in modo più coerente (se si consente alla shell di aprire i file anche per altri comandi) rispetto a quando greplo apre. E se il file non può essere aperto, grepnon viene nemmeno chiamato (che per alcuni comandi - forse no grep- può fare una grande differenza).
  • in grep line < in > out, se innon può essere aperto, outnon verrà creato o troncato.
  • Non ci sono problemi con alcuni file con nomi insoliti (come -o nomi di file che iniziano con -) ².
  • cosmetico: puoi posizionarlo <fileovunque sulla riga di comando per mostrare il flusso di comandi in modo più naturale, come <in grep line >outse preferissi.
  • cosmetico: con GNU grep, puoi scegliere quale etichetta usare davanti alla linea corrispondente anziché solo il nome del file come in:

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

In termini di prestazioni, se il file non può essere aperto, si salva l'esecuzione di grepquando si utilizza il reindirizzamento, ma per il resto grepnon mi aspetto molta differenza.

Con il reindirizzamento, risparmi di dover passare un argomento in più grep, rendi grepl'analisi dell'argomento leggermente più semplice. D'altra parte, la shell avrà bisogno (almeno) di una chiamata di sistema aggiuntiva al dup2()descrittore di file sul descrittore di file 0.

In { grep -m1 line; next command; } < file, grep(qui GNU grep) vorrà seek()tornare subito dopo la riga corrispondente in modo che next commandil resto del file sia visibile (dovrà anche determinare se il file è ricercabile o meno). In altre parole, la posizione all'interno di stdin è un'altra delle grepuscite. Con grep -m1 line file, può ottimizzarlo, è una cosa in meno grepdi cui preoccuparsi.


Gli appunti

¹ Con zsh, puoi fare:

grep line < file1 < file2

ma ciò equivale a cat file1 file2 | grep line(senza invocare l' catutilità) e quindi è meno efficiente, può causare confusione se il primo file non termina con un carattere di nuova riga e non ti farà sapere in quale file si trova il modello.

² Nel caso di ksh93e bash, tuttavia, ci sono file come /dev/tcp/host/port(e /dev/fd/xsu alcuni sistemi in bash) che, quando utilizzati nella destinazione dei reindirizzamenti, la shell intercetta per scopi speciali invece di aprire realmente il file sul file system (sebbene generalmente, quei file non esiste nel file system). /dev/stdinserve allo stesso scopo -riconosciuto grep, ma almeno qui è più propriamente spaziato (chiunque può creare un file chiamato -in qualsiasi directory, mentre solo gli amministratori possono creare un file chiamato /dev/tcp/host/porte gli amministratori dovrebbero conoscerlo meglio).


+1, per la bella spiegazione. Ho un dubbio: nel 2 ° caso quando la shell apre il file passa il contenuto del file aperto allo standard input (tastiera) ?? (Mi sono confuso con il termine "input standard di grep").
Ankit

1
@Ankit, stdin è dove le applicazioni leggono il loro input di default, il descrittore di file 0. Quando in un terminale, fd 0 viene aperto dalla lettura sul dispositivo terminale (qualcosa come / dev / ttyxx o / dev / pts / n). È così che finiscono per ottenere ciò che digiti sulla tastiera. Il reindirizzamento della shell dello stdin di un comando apre appena il fd 0 su qualche altro file prima di eseguire il comando.
Stéphane Chazelas,

6

La risposta di StephaneChazelas copre grep(1)e la maggior parte dei comandi di discendenza Unix funzionano in questo modo, ma non tutti. È standard leggere o dallo standard input (dalla tastiera, da un file reindirizzato via < file, o dall'output reindirizzato da un altro comando, esempio stupido ls * | grep '^ab*c$'), o dai file forniti come argomenti, come grep comment file1 file2 file3. Alcuni comandi usano la convenzione in base alla quale il file denominato -è input standard, quindi puoi dire make-middle | cat head - taildi ottenere uno stream head, qualunque cosa gen-middlegeneri, seguito da tail. Questo è di progettazione, per dare flessibilità nell'uso dei comandi.

Che è migliore? Finché funziona, cmd fileè più corto di cmd < file; potrebbe esserci una piccola differenza nel tempo tra la shell che fa il file frobbing ( <) e il comando che lo fa da sola, ma probabilmente è impercettibile a meno che tu non faccia nient'altro per tutto il giorno. Dipenderà da considerazioni come i professionisti citati nella risposta di Stephane.


cmd filenon è più breve di cmd<fileperò.
Stéphane Chazelas,

Tuttavia, è un tasto più breve, presumendo che sia necessario premere Maiusc per digitare a <.
DopeGhoti,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.