Na man greppágina (no Debian):
DESCRIÇÃO
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.
No primeiro caso, grepabre o arquivo; no segundo, o shell abre o arquivo e o atribui à entrada padrão de grep, e grepnão sendo transmitido nenhum argumento de nome de arquivo, pressupõe que ele precise cumprimentar sua entrada padrão.
Prós de 1:
grep pode receber mais de um arquivo¹.
greppode exibir o nome do arquivo em que cada ocorrência lineé encontrada.
Prós de 2:
- Se o arquivo não puder ser aberto, o shell retornará um erro que incluirá informações mais relevantes (como número da linha no script) e de maneira mais consistente (se você permitir que o shell abra arquivos para outros comandos também) do que quando
grepabre. E se o arquivo não puder ser aberto, grepnem será chamado (o que para alguns comandos - talvez não grep- possa fazer uma grande diferença).
- em
grep line < in > out, se innão pode ser aberto, outnão será criado ou truncado.
- Não há problema com alguns arquivos com nomes incomuns (como
-nomes de arquivos ou começando com -) ².
- cosmético: você pode colocar
<fileem qualquer lugar da linha de comando para mostrar o fluxo de comando com mais naturalidade, como <in grep line >outse preferir.
cosmético: com o GNU grep, você pode escolher qual rótulo usar na frente da linha correspondente, em vez de apenas o nome do arquivo, como em:
<file grep --label='Found in file at line' -Hn line
Em termos de desempenho, se o arquivo não puder ser aberto, você salva a execução grepao usar o redirecionamento, mas, caso contrário grep, não espero muita diferença.
Com o redirecionamento, você economiza a necessidade de passar um argumento extra para grepfacilitar grepa análise do argumento. Por outro lado, o shell precisará (pelo menos) de uma chamada extra do sistema para dup2()o descritor de arquivo no descritor de arquivo 0.
Em { grep -m1 line; next command; } < file, grep(aqui o GNU grep) desejará seek()retornar logo após a linha correspondente, para que next commandveja o restante do arquivo (ele também precisará determinar se o arquivo é procurável ou não). Em outras palavras, a posição dentro de stdin é outra da grepsaída. Com grep -m1 line fileisso, ele pode otimizar isso, é menos uma coisa para grepse preocupar.
Notas
¹ Com zsh, você pode fazer:
grep line < file1 < file2
mas isso equivale a cat file1 file2 | grep line(sem chamar o catutilitário) e, portanto, é menos eficiente, pode causar confusão se o primeiro arquivo não terminar em um caractere de nova linha e não informar em qual arquivo o padrão foi encontrado.
² No caso ksh93e no bashentanto, existem arquivos como /dev/tcp/host/port(e /dev/fd/xem alguns sistemas bash) que, quando usado no destino de redirecionamentos, o shell intercepta para fins especiais, em vez de realmente abrir o arquivo no sistema de arquivos (embora geralmente esses arquivos não existe no sistema de arquivos). /dev/stdinserve para o mesmo propósito que o -reconhecido por grep, mas pelo menos aqui está no espaço para nome mais adequado (qualquer pessoa pode criar um arquivo chamado -em qualquer diretório, enquanto apenas os administradores podem criar um arquivo chamado /dev/tcp/host/porte os administradores devem saber melhor).