find & sed (pesquisar e substituir)

27

Estou usando o seguinte comando no meu mac:

$find . -name “*.java” -exec sed -i ’s/foo/bar/g’ {} \;

e parece não ter efeito.

Eu tenho dois arquivos no diretório que terminam em .java, ambos com o texto foo. Estou esquecendo de algo?

EDIT: Resultados da solicitação de comentários

[aafghani-03:~/test amirafghani]$ find . -name "*.java" -exec sed -i 's/foo/bar/g' {} \;
sed: 1: "./bar.java": invalid command code .
sed: 1: "./foo.java": invalid command code .
Amir Afghani
fonte
2
É exatamente isso que você está executando? E se você remover o -exece tudo depois dele? Ele imprime os nomes dos arquivos Java? (Eu estou preocupado que você está usando aspas inteligentes em vez de aspas ASCII.)
Mikel
1
Na verdade, isso resolve, pelo menos para mim. As aspas duplas e simples devem ser substituídas por "e ', respectivamente.
precisa saber é
2
Citações inteligentes (?)! .. :)
Peter.O
O que eu colei foi exatamente o que eu estava correndo. Alguém pode postar uma resposta?
Amir Afghani
1
Da próxima vez, envie a mensagem de erro que você vê ao fazer a pergunta. Isso economizará tempo para todos.
Mikel

Respostas:

34

Antes de tudo, verifique se você está usando aspas ASCII regulares como "e '(códigos ASCII 0x22e 0x27, respectivamente) em scripts de shell, porque o exemplo na sua postagem contém caracteres de aspas não padrão. Se você olhar de perto, eles parecerão um pouco diferentes. Provavelmente, esse é um erro de copiar e colar de um formato de documento rich text como Word, OOWriter ou até mesmo uma janela do navegador.

Como você está em um Mac, provavelmente possui a implementação do FreeBSD sed, nesse caso você deve escrever o comando desta maneira:

find . -name "*.java" -exec sed -i '' s/foo/bar/g {} +

(aqui usando em +vez de \;para evitar a execução de uma sedchamada por arquivo).

Na implementação do FreeBSD, seda -iflag precisa de um argumento: a extensão de um arquivo de backup. Por exemplo, com -i .bako comando faria um backup file1.txtcomo file1.txt.bakprimeiro antes de realizar a substituição do arquivo original. Usar um argumento vazio ''significa não usar um arquivo de backup, que parece ser o que você deseja.

O mesmo na implementação do GNU (ou NetBSD, OpenBSD, busybox) seria:

find . -name "*.java" -exec sed -i s/foo/bar/g {} +

Obrigado @bahamat e @Mikel e @ pieter-breed por melhorar minha resposta com seus comentários.

Pare o dano contínuo a Monica
fonte
O que os aparelhos encaracolados fazem?
Zane Hitchcox
3
@ZaneHitchcox as chaves são espaços reservados para o nome do arquivo combinado
Pare de dano contínuo para Monica