Respostas:
O OS X usa uma combinação de ferramentas BSD e GNU, portanto, é melhor sempre verificar a documentação (apesar de eu ter uma que less
nem estava em conformidade com a página de manual do OS X):
sed usa o argumento depois -i
como extensão para backups. Forneça uma string vazia ( -i ''
) para nenhum backup.
O seguinte deve fazer:
LC_ALL=C find . -type f -name '*.txt' -exec sed -i '' s/this/that/ {} +
A -type f
é apenas uma boa prática; O sed reclamará se você fornecer um diretório ou algo assim.
-exec
é preferido sobre xargs
; você não precisa se preocupar com -print0
nada. O {} +
no final significa que find
anexará todos os resultados como argumentos a uma instância do comando chamado, em vez de executá-lo novamente para cada resultado. (Uma exceção é quando o número máximo de argumentos de linha de comando permitidos pelo sistema operacional é violado; nesse caso, find
será executado mais de uma instância.)
%
caráter: sed "s%localhost/site%blah/blah%"
. Outra alternativa é a barra invertida escapar do separador: sed "s/localhost\/site/blah\/blah/"
.
illegal byte sequence
erro? se assim for, tente LC_ALL=C find . -type f -name '*.txt' -exec sed -i '' s/this/that/ {} +
:, funcionou para mim.
/g
de múltiplas ocurrencies comoLC_ALL=C find . -type f -exec sed -i '' s/search/replace/g {} +
Para o mac, uma abordagem mais semelhante seria a seguinte:
find . -name '*.txt' -print0 | xargs -0 sed -i "" "s/form/forms/g"
find . -name '*.php' -print0 | xargs -0 sed -i "" "s/easyform/form360/g"
Como solução alternativa, estou usando esta no Mac OSX 10.7.5
grep -ilr 'old-word' * | xargs -I@ sed -i '' 's/old-word/new-word/g' @
O crédito vai para: resposta de Todd Cesere
Nenhuma das opções acima funciona no OSX.
Faça o seguinte:
perl -pi -w -e 's/SEARCH_FOR/REPLACE_WITH/g;' *.txt
Uma versão que funciona no Linux e no Mac OS X (adicionando a -e
opção a sed
):
export LC_CTYPE=C LANG=C
find . -name '*.txt' -print0 | xargs -0 sed -i -e 's/this/that/g'
export LC_CTYPE=C && export LANG=C
Sempre que digito esse comando, sempre pareço manejá-lo ou esquecer uma bandeira. Criei um Gist no github baseado na resposta do TaylanUB que substitui uma descoberta global do diretório atual. Isso é específico do Mac OSX.
https://gist.github.com/nateflink/9056302
É legal porque agora eu apenas abro um terminal e copio:
curl -s https://gist.github.com/nateflink/9056302/raw/findreplaceosx.sh | bash -s "find-a-url.com" "replace-a-url.com"
Você pode obter alguns erros estranhos na sequência de bytes, então aqui está o código completo:
#!/bin/bash
#By Nate Flink
#Invoke on the terminal like this
#curl -s https://gist.github.com/nateflink/9056302/raw/findreplaceosx.sh | bash -s "find-a-url.com" "replace-a-url.com"
if [ -z "$1" ] || [ -z "$2" ]; then
echo "Usage: ./$0 [find string] [replace string]"
exit 1
fi
FIND=$1
REPLACE=$2
#needed for byte sequence error in ascii to utf conversion on OSX
export LC_CTYPE=C;
export LANG=C;
#sed -i "" is needed by the osx version of sed (instead of sed -i)
find . -type f -exec sed -i "" "s|${FIND}|${REPLACE}|g" {} +
exit 0
Usei esse formato - mas ... descobri que precisava executá-lo três ou mais vezes para que ele realmente alterasse todas as instâncias que eu achava extremamente estranhas. A execução uma vez alteraria algumas em cada arquivo, mas não todas. Executar exatamente a mesma string duas a quatro vezes capturaria todas as instâncias.
find . -type f -name '*.txt' -exec sed -i '' s/thistext/newtext/ {} +
g
porque o seu regex sed precisa de um no final, caso contrário, ele substitui apenas a primeira ocorrência de thistext
uma linha. Portanto, o seu regex deve sers/thistext/newtext/g
https://bitbucket.org/masonicboom/serp é um utilitário go (ou seja, multiplataforma), testado no OSX, que pesquisa e substitui recursivamente o texto em arquivos em um determinado diretório e confirma cada substituição. É novo, então pode ser de buggy.
O uso se parece com:
$ ls test
a d d2 z
$ cat test/z
hi
$ ./serp --root test --search hi --replace bye --pattern "*"
test/z: replace hi with bye? (y/[n]) y
$ cat test/z
bye
find . -type f | xargs sed -i '' 's/string1/string2/g'
Consulte aqui para mais informações.
O comando no OSX deve ser exatamente o mesmo que é o Unix sob a bonita interface do usuário.
-print0
adicionar aos find
sinalizadores e -0
aos xargs
sinalizadores.
-exec sed -i s/this/that/g {} \+
vez de -print
e xargs
xargs
poderá ver o "./jacobus" delimitado por espaço como um arquivo para o qual passar e sed
, em seguida, com "R.txt" , nenhum dos quais existe.
poderia apenas dizer $ PWD em vez de "."
apple.stackexchange.com
pois não é genérico o suficiente para linux nem todos os desenvolvedores.