Desde la man grep
página (en Debian):
DESCRIPCIÓN
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.
En el primer caso, grep
abre el archivo; en el segundo, el shell abre el archivo y lo asigna a la entrada estándar de grep
, y al grep
no pasar ningún argumento de nombre de archivo se asume que necesita grep su entrada estándar.
Pros de 1:
grep
puede grep más de un archivo¹.
grep
puede mostrar el nombre del archivo donde se encuentra cada aparición de line
.
Pros de 2:
- Si el archivo no se puede abrir, el shell devuelve un error que incluirá información más relevante (como el número de línea en la secuencia de comandos) y de una manera más consistente (si deja que el shell también abra archivos para otros comandos) que cuando
grep
lo abre Y si el archivo no se puede abrir, grep
ni siquiera se llama (lo que para algunos comandos, tal vez no grep
, puede marcar una gran diferencia).
- en
grep line < in > out
, si in
no se puede abrir, out
no se creará ni truncará.
- No hay problema con algunos archivos con nombres inusuales (como
-
o nombres de archivos que comienzan con -
) ².
- cosmético: puede colocarlo en
<file
cualquier lugar de la línea de comandos para mostrar el flujo de comandos de forma más natural, como <in grep line >out
si lo prefiere.
cosmética: con GNU grep
, puede elegir qué etiqueta usar delante de la línea correspondiente en lugar de solo el nombre del archivo como en:
<file grep --label='Found in file at line' -Hn line
En términos de rendimiento, si el archivo no se puede abrir, guarda la ejecución de grep
cuando usa la redirección, pero de lo contrario grep
, no espero mucha diferencia.
Con la redirección, ahorra tener que pasar un argumento adicional grep
, hace que grep
el análisis de argumentos sea un poco más fácil. Por otro lado, el shell necesitará (al menos) una llamada de sistema adicional al dup2()
descriptor de archivo en el descriptor de archivo 0.
En { grep -m1 line; next command; } < file
, grep
(aquí GNU grep
) querrá seek()
regresar justo después de la línea coincidente para que next command
vea el resto del archivo (también deberá determinar si el archivo es buscable o no). En otras palabras, la posición dentro de stdin es otra de grep
las salidas. Congrep -m1 line file
eso, puede optimizar eso, eso es algo menos por lo grep
que preocuparse.
Notas
¹ Con zsh
, puedes hacer:
grep line < file1 < file2
pero eso es el equivalente de cat file1 file2 | grep line
(sin invocar elcat
utilidad) y, por lo tanto, es menos eficiente, puede causar confusión si el primer archivo no termina en un carácter de nueva línea y no le permite saber en qué archivo se encuentra el patrón.
² En el caso de ksh93
y bash
, sin embargo, hay archivos como /dev/tcp/host/port
(y /dev/fd/x
en algunos sistemas en bash
) que, cuando se usan en el destino de redirecciones, el shell intercepta para fines especiales en lugar de abrir realmente el archivo en el sistema de archivos (aunque generalmente, esos archivos no existe en el sistema de archivos). /dev/stdin
tiene el mismo propósito que el -
reconocido grep
, pero al menos aquí tiene un espacio de nombres más apropiado (cualquiera puede crear un archivo llamado -
en cualquier directorio, mientras que solo los administradores pueden crear un archivo llamado /dev/tcp/host/port
y los administradores deberían saberlo mejor).
La respuesta de StephaneChazelas cubre
grep(1)
, y la mayoría de los comandos de linaje de Unix funcionan de esa manera, pero no todos. Es estándar leer desde la entrada estándar (desde el teclado, desde un archivo redirigido a través de< file
, o desde la salida canalizada por otro comando, ejemplo estúpidols * | grep '^ab*c$'
), o desde el archivo (s) dado como argumento, comogrep comment file1 file2 file3
. Algunos comandos usan la convención de que el archivo nombrado-
es una entrada estándar, por lo que puede decirmake-middle | cat head - tail
que obtenga una secuencia conhead
lo quegen-middle
genere, seguido detail
. Esto es por diseño, para dar flexibilidad en el uso de los comandos.¿Cual es mejor? Mientras funcione,
cmd file
es más corto quecmd < file
; podría haber una pequeña diferencia en el tiempo entre el shell que hace el archivo frobbing (<
) y el comando que lo hace solo, pero probablemente no se note a menos que no haga nada más durante todo el día. Dependerá de consideraciones como las ventajas mencionadas en la respuesta de Stephane.fuente
cmd file
No es más corto quecmd<file
sin embargo.<
.