Kiedy powinienem używać przekierowania wejściowego?


21

Użyłem następujących dwóch poleceń, aby uzyskać te same wyniki:

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

Czy ktoś mógłby mi wyjaśnić wszelkie zalety / wady, jeśli któreś z tych dwóch podejść do siebie nawzajem.

Odpowiedzi:


28

Ze man grepstrony (w Debianie):

OPIS

   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.

W pierwszym przypadku grepotwiera plik; w drugim przypadku powłoka otwiera plik i przypisuje go do standardowego wejścia grep, a grepnie przekazanie żadnego argumentu nazwy pliku zakłada, że ​​należy grepować standardowe wejście.

Zalety 1:

  • grep może grep więcej niż jeden plik¹.
  • grepmoże wyświetlić nazwę pliku, w którym lineznaleziono każde wystąpienie .

Zalety 2:

  • Jeśli pliku nie można otworzyć, powłoka zwraca błąd, który będzie zawierał bardziej odpowiednie informacje (takie jak numer wiersza w skrypcie) i w bardziej spójny sposób (jeśli pozwolisz powłoce otwierać pliki również dla innych poleceń) niż wtedy, gdy grepotwiera to. A jeśli pliku nie można otworzyć, grepnie jest nawet wywoływany (co w przypadku niektórych poleceń - może nie grep- może mieć duże znaczenie).
  • w grep line < in > out, jeśli innie można go otworzyć, outnie zostanie utworzony ani obcięty.
  • Nie ma problemu z niektórymi plikami o nietypowych nazwach (np. -Lub nazwach rozpoczynających się od -) ².
  • kosmetyczny: możesz umieścić w <filedowolnym miejscu wiersza polecenia, aby wyświetlić przepływ poleceń w bardziej naturalny sposób, na przykład <in grep line >outjeśli wolisz.
  • kosmetyczny: w GNU grepmożesz wybrać, jakiej etykiety użyć przed pasującą linią zamiast samej nazwy pliku, jak w:

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

Jeśli chodzi o wydajność, jeśli pliku nie można otworzyć, zapisujesz wykonanie greppodczas korzystania z przekierowania, ale poza greptym nie oczekuję dużej różnicy.

Dzięki przekierowaniu oszczędzasz konieczności przekazywania dodatkowego argumentu grep, dzięki czemu grepparsowanie argumentów jest nieco łatwiejsze. Z drugiej strony powłoka będzie potrzebowała (przynajmniej) dodatkowego wywołania systemowego do dup2()deskryptora pliku na deskryptor pliku 0.

W { grep -m1 line; next command; } < file, grep(tutaj GNU grep) będzie chciał seek()wrócić do bezpośrednio po pasującej linii, więc next commandzobaczy resztę pliku (będzie musiał także ustalić, czy plik można zobaczyć, czy nie). Innymi słowy, pozycja w stdin jest kolejną z grepdanych wyjściowych. Dzięki grep -m1 line file, może to zoptymalizować, to jedna rzecz, o którą greptrzeba dbać.


Notatki

¹ Za pomocą zshmożesz:

grep line < file1 < file2

ale robi to odpowiednik cat file1 file2 | grep line(bez wywoływania catnarzędzia), a zatem jest mniej wydajny, może powodować zamieszanie, jeśli pierwszy plik nie kończy się znakiem nowej linii i nie informuje, w którym pliku znajduje się wzorzec.

² W przypadku ksh93i bashchociaż istnieją pliki takie jak /dev/tcp/host/port(i /dev/fd/xna niektórych systemach w bash), które, gdy są używane w celu przekierowań, powłoka przechwytuje w specjalnych celach zamiast tak naprawdę otwierać plik w systemie plików (choć ogólnie te pliki nie istnieją w systemie plików). /dev/stdinsłuży temu samemu celowi, który został -rozpoznany przez grep, ale przynajmniej tutaj jest to bardziej poprawna przestrzeń nazw (każdy może utworzyć plik o nazwie -w dowolnym katalogu, podczas gdy tylko administratorzy mogą utworzyć plik o nazwie /dev/tcp/host/porti administratorzy powinni wiedzieć lepiej).


+1, dla miłego wyjaśnienia. Mam jedno wątpliwości: w drugim przypadku, gdy powłoka otwiera plik, czy przekazuje zawartość otwartego pliku do standardowego wejścia (klawiatury)? (Myliłem się z terminem „standardowe wejście grep”).
Ankit

1
@Ankit, stdin to miejsce, w którym aplikacje domyślnie odczytują swoje dane wejściowe, deskryptor pliku 0. W terminalu fd 0 jest otwierany przed odczytem na urządzeniu końcowym (coś w rodzaju / dev / ttyxx lub / dev / pts / n). W ten sposób uzyskują to, co piszesz na klawiaturze. Przekierowanie powłoki stdin polecenia po prostu otwiera fd 0 do innego pliku przed wykonaniem polecenia.
Stéphane Chazelas

6

Odpowiedź StephaneChazelas obejmuje grep(1)i większość poleceń rodowodu Unix działa w ten sposób, ale nie wszystkie. Standardowo czytane jest albo ze standardowego wejścia (z klawiatury, z pliku przekierowanego przez < file, albo z danych wyjściowych potokowanych przez inne polecenie, głupi przykład ls * | grep '^ab*c$'), lub z pliku (-ów) podanych jako argumenty, jak grep comment file1 file2 file3. Niektóre polecenia używają konwencji, że plik o nazwie -jest standardowym wejściem, więc możesz powiedzieć, make-middle | cat head - tailże pobierasz strumień head, cokolwiek gen-middlegeneruje, a następnie tail. Ma to na celu zapewnienie elastyczności w stosowaniu poleceń.

Który jest lepszy? O ile działa, cmd filejest krótszy niż cmd < file; może istnieć niewielka różnica w czasie między powłoką wykonującą funkcję frobbing pliku ( <) a poleceniem wykonującą ją samodzielnie, ale prawdopodobnie niezauważalna, chyba że przez cały dzień nic nie robisz. Będzie to zależeć od rozważań takich jak profesjonaliści wspomniani w odpowiedzi Stephane'a.


cmd filenie jest krótszy niż cmd<filechociaż.
Stéphane Chazelas

Jest to jednak jedno naciśnięcie klawisza krótsze, zakładając, że musisz nacisnąć Shift, aby wpisać a <.
DopeGhoti
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.