Da página man grep (no Debian):
DESCRIPTION
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, grep abre o arquivo; no segundo, o shell abre o arquivo e o atribui à entrada padrão de grep , e grep não sendo passado a nenhum argumento de nome de arquivo, pressupõe que ele precisa ajustar sua entrada padrão.
Prós de 1:
-
greppode utilizar mais de um arquivo¹. -
greppode exibir o nome do arquivo onde cada ocorrência delineé 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 o número da linha no script) e de uma maneira mais consistente (se você permitir que os arquivos abertos do shell também sejam usados para outros comandos) ) do que quando
grepabre. E se o arquivo não puder ser aberto,grepnão é nem chamado (o que para alguns comandos - talvez nãogrep- pode fazer uma grande diferença). - em
grep line < in > out, seinnão puder ser aberto,outnão será criado nem truncado. - Não há problemas com alguns arquivos com nomes incomuns (como
-ou nomes de arquivos que começam com-) ². - cosmético: você pode colocar
<fileem qualquer lugar na linha de comando para mostrar o fluxo de comando mais naturalmente, como<in grep line >out, se preferir. -
cosmético: com o GNU
grep, você pode escolher o rótulo a ser usado 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ê salvará a execução de grep ao usar o redirecionamento, mas, por outro lado, para grep , não espero muita diferença.
Com o redirecionamento, você não precisa passar um argumento extra para grep , você torna a análise de argumentos de grep um pouco mais fácil. Por outro lado, o shell precisará (pelo menos) de uma chamada extra do sistema para dup2() do descritor de arquivo no descritor de arquivo 0.
Em { grep -m1 line; next command; } < file , grep (aqui GNU grep ) desejará seek() de volta para logo após a linha correspondente, então o next command verá o restante do arquivo (também será necessário determinar se o arquivo é procurado ou não). Em outras palavras, a posição dentro de stdin é outra da saída de grep . Com grep -m1 line file , pode otimizar isso, isso é uma coisa a menos para grep se importar.
Notas
¹ Com zsh , você pode fazer:
grep line < file1 < file2
mas que está fazendo o equivalente a cat file1 file2 | grep line (sem invocar o utilitário cat ) e, portanto, é menos eficiente, pode causar confusão se o primeiro arquivo não terminar em um caractere de nova linha e não o informar qual arquivo o padrão é encontrado.
² No caso de ksh93 e bash , existem arquivos como /dev/tcp/host/port (e /dev/fd/x em alguns sistemas em bash ) que, quando usados no destino de redirecionamentos que o shell intercepta para propósitos especiais em vez de realmente abrir o arquivo no sistema de arquivos (embora, geralmente, esses arquivos não existam no sistema de arquivos). /dev/stdin tem o mesmo propósito que - reconhecido por grep , mas pelo menos aqui é mais apropriadamente namespaced (qualquer um pode criar um arquivo chamado - em qualquer diretório, enquanto apenas administradores podem criar um arquivo chamado /dev/tcp/host/port e os administradores devem saber melhor).