Como posso passar strings com aspas simples para o grep?

Como posso passar strings com aspas simples para o grep?

Meu resultado desejado é o seguinte: pesquisar recursivamente um diretório procurando uma determinada string em todos os arquivos encontrados. O seguinte comando é meu porto de escala habitual:

find ./ | xargs grep -ns 'foobar'

No entanto, quando foobarhá aspas, o comando falha e me fornece um >prompt no shell. O comando específico que está causando o problema é o seguinte:

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

Tentei escapar das aspas com barras invertidas, mas sem sucesso. Qual é a maneira correta de fazer isso?

Responder1

As aspas simples são encerradas por aspas simples; todos os outros caracteres intermediários são preservados exatamente como estão, incluindo barras invertidas. Portanto, não há como incorporar uma aspa simples entre aspas simples. (Mas vocêpodeterminar as aspas simples, escapar de uma aspa simples e iniciar um novo conjunto de aspas simples, como em 'Single quotes aren'\''t ever really embedded in single quotes.')

Sugestão:Evite find+xargs quando grep -r pattern .puder fazer grep recursivamente no diretório atual.

Os comandos abaixo têm comportamento equivalente:

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

O último comando é interpretado como:

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

Concatenando essas partes, o grepcomando recebe o argumento add_action('save_post',.

Responder2

xargsespera argumentos citados de alguma forma estranha que findnão produz. Nunca use xargsem combinação com find, a menos que você saiba que os nomes dos arquivos não contêm \"'espaços em branco.

Em vez de usar xargs, findchame diretamente o programa que deseja executar.

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

Com exec … {} +, o programa é invocado uma vez para vários arquivos de uma só vez, como com xargs. Algumas versões mais antigas findnão suportam +aqui¹, então você deve usar ;, que invoca grepuma vez por arquivo.

Como alternativa, você pode usar find … -print0 | xargs -0, se seus utilitários suportarem¹. A -print0opção diz findpara emitir nomes separados por um byte nulo e -0diz xargspara esperar uma entrada separada por nulo e não fazer nenhuma interpretação de aspas.

Observe a citação acima: entre aspas simples, todos os caracteres são interpretados literalmente, exceto que 'significa o fim da string literal. Portanto, '\''é efetivamente uma maneira de colocar aspas simples literais dentro de uma string entre aspas simples; formalmente, é “ 'aspa final, aspa simples \literal ', 'aspa inicial”.

No caso especial de grep, se sua implementação suportar¹, você pode dispensar finde usar grep -rpara pesquisar dentro de um diretório recursivamente:

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

¹ Linux, Cygwin, FreeBSD e OSX suportam esses recursos.

Responder3

grep "add_action('save_post'," ./* -R
  1. Você pode executar grep em todos os arquivos no diretório atual recursivamente com -Ra opção.

  2. A string de pesquisa pode ser cercada por ".

informação relacionada