¿Cómo funciona esta [t] ricky bracket expression en grep?

38

Recientemente vi esta frase:

$ ps -ef | grep [f]irefox 

thorsen   16730     1  1 Jun19 ?        00:27:27 /usr/lib/firefox/firefox ...

Por lo tanto, parece devolver la lista de procesos con "firefox" en los datos pero dejando de lado el proceso grep, y por lo tanto parece más o menos equivalente a:

ps -ef |grep -v grep| grep firefox

Sin embargo, no puedo entender cómo funciona. He mirado la página man en grep y en otros lugares, pero no he encontrado una explicación.

Y para complicar el misterio si corro:

$ ps -ef | grep firefox  > data
$ grep [f]irefox data

thorsen   15820 28618  0 07:28 pts/1    00:00:00 grep --color=auto firefox
thorsen   16730     1  1 Jun19 ?        00:27:45 /usr/lib/firefox/firefox ....

¡el [t] rick parece dejar de funcionar!

Alguien aquí sabrá lo que está sucediendo, estoy seguro.

Gracias.

Thorsen
fuente
Hmm, ¿estás seguro de que esto es correcto? ps -eaf | grep [fF] irefox tendría más sentido. Esto se ve como una expresión regular y en el medio coincide con cualquiera de los caracteres incluidos. También se puede hacer como rango, p. Ej. [0-9]
mbs
Bueno, sí. Ese era el problema que tenía: una clase de personaje que contenía solo un personaje parecía inútil, ¡pero producía un efecto secundario "misterioso"! De todos modos, jokerdino ha proporcionado una buena explicación.
Thorsen

Respuestas:

57

La expresión de corchetes forma parte de la coincidencia de patrones de clase de caracteres de grep con bash shell (y también otros shells) .

El grepprograma por defecto comprende las expresiones regulares básicas POSIX. Con eso puedes definir clases de personajes. Por ejemplo ps -ef | grep [ab9]irefox, encontraría " a irefox", " b irefox", " 9 irefox" si existieran, pero no " ab irefox".

El comando grep [a-zA-Z0-9]irefoxincluso encontraría todos los procesos que comienzan con exactamente una letra o número y terminan en "irefox".

Entonces ps -ef | grep firefoxbusca líneas con firefoxél. Dado que el proceso grep en sí mismo tiene "firefox", grep también lo encuentra. Al agregar una [], solo estamos buscando la clase de caracteres "[f]" (que consiste solo en la letra "f" y es equivalente a solo una "f" sin los corchetes). La ventaja de los corchetes ahora es que la cadena "firefox" ya no aparece en el comando grep. Por lo tanto, grep no aparecerá en el resultado de grep.

Debido a que no muchas personas están familiarizadas con los corchetes como coincidencia de clase de caracteres y expresiones regulares en general, el segundo resultado puede parecer un poco misterioso.

Si desea corregir el segundo resultado, puede usarlos de esta manera:

ps -ef | grep [f]irefox  > data
grep firefox data

(Referencia)

jokerdino
fuente
1
Hmm No se me ocurrió que el [] era algo interpretado por el caparazón ANTES de que grep tuviera una oportunidad. Gracias por la explicación. Todos los [m] años resueltos.
Thorsen
Feliz de ayudar. Que tengas un buen día :)
jokerdino
1
En bash, los corchetes se pasarán a grep si no hay coincidencia para la palabra en la que se encuentran (es decir, ningún archivo llamado "firefox" en el directorio actual). Sin embargo, grep también tiene clases de caracteres y [f] en grep es igual a f.
Daniel Hershcovich
66
En realidad, en este caso, no creo que sea interpretado por el shell antes de grep. Creo que [f]es el corchete de coincidencia del patrón de expresión regular para las clases de caracteres. Como en "[a-z0-9] irefox" grep también coincidiría con "airefox" y "0irefox". Puede ver fácilmente que no es un bash incorporado ya que echo $([f])devuelve un error.
con-f-use
44
La razón específica [f]irefoxpara este propósito es que el shell no lo expande. Cuando el shell se expande [f]irefoxa firefox, eso hace grepque se vea firefox, y luego firefoxes parte de grepla cadena de comando de, exactamente como si grep firefoxse ejecutara. Pero es bueno para mantener la coincidencia de patrones de shell en cuenta , sobre todo cuando secuencias de comandos, porque si hay un archivo llamado firefoxen el directorio actual , entonces la cáscara no ampliar [f]irefoxafirefox y este método falla, es decir, la greplínea de la psque se muestra.
Eliah Kagan
10

La razón es que la cadena

grep firefox

coincide con el patrón firefox, pero la cadena

grep [f]irefox

no coincide con el patrón [f]irefox(que es equivalente al patrón firefox).

Es por eso que el primer grep coincide con su propia línea de comando de proceso, mientras que el segundo no.

Daniel Hershcovich
fuente
Esto hace que me duela aún más la cabeza
Pithikos