Quiero saber qué archivos tienen la cadena $Id$.

grep \$Id\$ my_dir/mylist_of_files 

devuelve 0 ocurrencias.

Descubrí que tengo que usar

grep \$Id$ my_dir/mylist_of_files

Entonces veo que $Id está coloreado en la salida, es decir, se ha emparejado.

¿Cómo podría hacer coincidir el segundo $ y por qué no «t \$Id\$ funciona.

No importa si el segundo $ es el último carácter o no.

Yo uso grep 2.9.


Antes publicando mi pregunta, usé Google …

Encontré una respuesta

Para buscar un $ (signo de dólar) en el archivo llamado test2, ingrese:

grep \\ $ test2

Los caracteres \\ (doble barra invertida) son necesarios para forzar al shell a pasar un \ $ (barra invertida simple, signo de dólar) al comando grep. El carácter \ (barra diagonal inversa simple) le dice al comando grep que trate el siguiente carácter (en este ejemplo, $) como un carácter literal en lugar de un carácter de expresión. Use el comando fgrep para evitar la necesidad de usar caracteres de escape como la barra invertida.

pero no entiendo por qué grep \$Id funciona y por qué grep \\$Id\\$ no «t».

Estoy un poco confundido …

Respuesta

Aquí hay 2 problemas distintos.

  1. grep utiliza Expresiones regulares básicas (BRE) y $ es un carácter especial en BRE «s solo al final de una expresión. La consecuencia de esto es que las 2 instancias de $ en $Id$ no son iguales. el primero es un carácter normal y el segundo es un ancla que coincide con el final de la línea. Para que el segundo $ coincida con un $ tendrá que escapar de la barra invertida, es decir, $Id\$. Escapar el primer $ también funciona: \$Id\$, y prefiero esto porque parece más consistente.¹

  2. Hay dos mecanismos de escape / citación completamente no relacionados en funcionamiento aquí: citación de shell y citación de barra invertida de expresiones regulares. El problema es que muchos caracteres que usan las expresiones regulares también son especiales para el shell y, además, el carácter de escape de expresiones regulares, la barra invertida, también es un carácter de comillas del shell. Esta es la razón por la que a menudo ves errores que involucran barras invertidas dobles, pero no recomiendo usar barras invertidas para el shell que cita expresiones regulares porque no es muy legible.

    En cambio, la forma más sencilla de hacerlo es poner primero tu toda la expresión regular entre comillas simples como en "regex". La comilla simple es la forma más fuerte de citar que tiene el shell, por lo que siempre que su expresión regular no contenga comillas simples, ya no tendrá que preocuparse por las comillas del shell y podrá concentrarse en la sintaxis BRE pura.

Entonces, aplicando esto de nuevo a su ejemplo original, arrojemos la expresión regular correcta (\$Id\$) entre comillas simples. Lo siguiente debería hacer lo que quiere:

grep "\$Id\$" my_dir/my_file 

La razón por la que \$Id\$ no funciona es porque después de eliminar las comillas de shell (la forma más correcta de decir shell entre comillas), la expresión regular que grep ve es $Id$. Como se explica en (1.), esta expresión regular coincide con una $Id solo al final de una línea porque el primer $ es literal mientras que el segundo es un carácter de ancla especial.

¹ Tenga en cuenta también que si alguna vez cambia a Expresiones regulares extendidas (ERE), por ejemplo, si decide usar egrep (o grep -E), el carácter $ es siempre especial. En ERE, «s $Id$ nunca coincidiría con nada porque no puede tener caracteres después del final de una línea, así que \$Id\$ sería el único camino a seguir.

Comentarios

  • Para evitar que grep interprete su primer parámetro como una expresión regular , también puedes hacer grep -F '$Id$'.
  • En mi shell (bash 4.3.42) grep '$Id\$' ... y grep \$Id\\$ ... funciona
  • Y si este es un comando en un archivo MAKE, también debe escapar del $ con un $: grep '$$Id\$$'. stackoverflow.com / a / 2382810/2097284

Responder

Para buscar $Id$ en un archivo: puede usar: grep "\$id*" filename

Comentarios

  • Eso coincidirá con cualquier cosa que comience con $id, así que $idea también, por ejemplo, no solo $id$ .

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *