¿Cómo puedo pasar cadenas con comillas simples a grep?

¿Cómo puedo pasar cadenas con comillas simples a grep?

El resultado que deseo es el siguiente: buscar recursivamente en un directorio una cadena determinada en todos los archivos encontrados. El siguiente comando es mi puerto de escala habitual:

find ./ | xargs grep -ns 'foobar'

Sin embargo, cuando foobartiene comillas, el comando falla y me muestra un >mensaje en el shell. El comando específico que está causando el problema es el siguiente:

find ./ | xargs grep -ns 'add_action(\'save_post\','

Intenté escapar de las comillas con barras invertidas, pero fue en vano. ¿Cuál es la forma correcta de hacer esto?

Respuesta1

Las comillas simples terminan con comillas simples; todos los demás caracteres intermedios se conservan exactamente como están, incluidas las barras invertidas. Por lo tanto, no hay forma de insertar una comilla simple entre comillas simples. (Pero tupoderfinalice las comillas simples, escape una comilla simple y comience un nuevo conjunto de comillas simples, como en 'Single quotes aren'\''t ever really embedded in single quotes.')

Sugerencia:Evite buscar + xargs cuando grep -r pattern .pueda realizar búsquedas recursivas en el directorio actual.

Los siguientes comandos tienen un comportamiento equivalente:

grep -rns "add_action('save_post'," .
grep -rns 'add_action('\'save_post\', .

El último comando se interpreta como:

  1. 'add_action('->add_action(
  2. \'->'
  3. save_post->save_post
  4. \'->'
  5. ,->,

Concatenando estas partes, el grepcomando recibe el argumento add_action('save_post',.

Respuesta2

xargsespera argumentos citados de alguna manera extraña que findno produce. Nunca lo use xargsen combinación con find, a menos que sepa que los nombres de sus archivos no contienen \"'espacios en blanco.

En lugar de usar xargs, findllame directamente al programa que desea ejecutar.

find . -exec grep -ns 'add_action('\''save_post'\'',' {} +

Con exec … {} +, el programa se invoca una vez para muchos archivos a la vez, como con xargs. Algunas versiones anteriores de findno son compatibles +aquí¹, entonces debes usar ;en su lugar, que invoca grepuna vez por archivo.

Alternativamente, puedes usar find … -print0 | xargs -0, si tus servicios públicos lo admiten¹. La -print0opción indica findque se emitan nombres separados por un byte nulo y -0que xargsse espere una entrada separada por nulos y que no se realice ninguna interpretación de comillas.

Tenga en cuenta las citas anteriores: entre comillas simples, todos los caracteres se interpretan literalmente, excepto el que 'indica el final de la cadena literal. Entonces, '\''es efectivamente una forma de poner una comilla simple literal dentro de una cadena entre comillas simples; formalmente, es “ 'comilla final, comilla simple \literal ', 'comilla inicial”.

En el caso especial de grep, si su implementación lo admite¹, puede prescindir findy utilizar grep -rpara buscar dentro de un directorio de forma recursiva:

grep -r 'add_action('\''save_post'\'',' .

¹ Linux, Cygwin, FreeBSD y OSX admiten estas funciones.

Respuesta3

grep "add_action('save_post'," ./* -R
  1. Puede recuperar todos los archivos en el directorio actual de forma recursiva con -Rla opción.

  2. La cadena de búsqueda puede estar rodeada por ".

información relacionada