Como posso passar strings com aspas simples para grep?

3

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

find ./ | xargs grep -ns 'foobar'

No entanto, quando foobar tem 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\','

Eu tentei escapar das citações com barras invertidas, mas sem sucesso. Qual é a maneira correta de fazer isso?

    
por Matthew 03.04.2012 / 11:33

3 respostas

6

As aspas simples são terminadas por aspas simples; todos os outros personagens intermediários são preservados exatamente como estão, incluindo barras invertidas. Assim, não há como incorporar uma única citação entre aspas simples. (Mas você pode terminar 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 localizar + xargs quando grep -r pattern . puder recursivamente utilizar o diretório atual.

Os comandos abaixo têm um comportamento equivalente:

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

O último comando é interpretado como:

  1. 'add_action(' - > %código%
  2. add_action( - > %código%
  3. \' - > %código%
  4. ' - > %código%
  5. save_post - > %código%

Concatenando essas partes, o comando save_post recebe o argumento \' .

    
por 03.04.2012 / 11:52
2

xargs espera argumentos citados de uma maneira estranha que find não produz. Nunca use xargs em combinação com find , a menos que você saiba que os nomes dos arquivos não contêm \"' ou espaço em branco.

Em vez de usar xargs , deixe find chamar diretamente o programa que você deseja executar.

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

Com exec … {} + , o programa é chamado uma vez para muitos arquivos de uma vez, como acontece com xargs . Algumas versões mais antigas de find não suportam + here¹, então você tem que usar ; , que invoca grep uma vez por arquivo.

Você pode, alternativamente, usar find … -print0 | xargs -0 , se seus utilitários suportarem it¹. A opção -print0 informa a find a emitir nomes separados por um byte nulo e -0 indica xargs a esperar entradas separadas por nulo e a não fazer qualquer interpretação de aspas.

Observe a citação acima: entre aspas simples, todos os caracteres são interpretados literalmente, exceto que ' significa o final da string literal. Portanto, '\'' é efetivamente uma maneira de colocar uma aspa simples literal dentro de uma cadeia de aspas simples; formalmente, é " ' end quote, \ literal ' aspas simples, ' begin quote".

No caso especial de grep , se a sua implementação suportar, você pode dispensar find e usar grep -r para pesquisar dentro de um diretório recursivamente:

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

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

    
por 04.04.2012 / 03:03
1
grep "add_action('save_post'," ./* -R
  1. Você pode usar todos os arquivos no diretório atual de forma recursiva com a opção -R .

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

por 03.04.2012 / 11:42