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:
-
grep
pode utilizar mais de um arquivo¹. -
grep
pode 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
grep
abre. E se o arquivo não puder ser aberto,grep
não é nem chamado (o que para alguns comandos - talvez nãogrep
- pode fazer uma grande diferença). - em
grep line < in > out
, sein
não puder ser aberto,out
nã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
<file
em 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).