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).