Dica: Não faça o abaixo em uma árvore de check-out svn ... ele substituirá os arquivos mágicos da pasta .svn.
J. Polfer
7
Oh meu Deus, isso é exatamente o que eu acabei de fazer. Mas funcionou e não parece ter causado nenhum mal. Qual é o pior que poderia acontecer?
23413 Katzwinkel
5
@ J.Katzwinkel: no mínimo, pode danificar as somas de verificação, o que pode danificar seu repositório.
Ninjagecko 14/05
3
Dica rápida para todas as pessoas que usam o sed: ele adicionará novas linhas finais aos seus arquivos. Se você não os quiser, primeiro faça uma busca-substituição que não corresponda a nada e comprometa-a com o git. Então faça o real. Em seguida, faça uma nova recuperação interativa e exclua a primeira.
funroll
5
Você pode excluir um diretório, como git, a partir dos resultados usando -path ./.git -prune -oem find . -path ./.git -prune -o -type f -name '*matchThisText*' -print0antes de tubulação para xargs
devinbost
Respostas:
849
find /home/www \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'
-print0diz findpara imprimir cada um dos resultados separados por um caractere nulo, em vez de uma nova linha. No caso improvável de o seu diretório ter arquivos com novas linhas nos nomes, isso ainda permite xargstrabalhar nos nomes de arquivos corretos.
\( -type d -name .git -prune \)é uma expressão que pula completamente todos os diretórios nomeados .git. Você pode expandi-lo facilmente, se você usa o SVN ou tem outras pastas que deseja preservar - basta comparar com mais nomes. É aproximadamente equivalente a -not -path .git, mas mais eficiente, porque, em vez de verificar todos os arquivos no diretório, ignora-o completamente. O -odepois é necessário por causa de como -prunerealmente funciona.
No OSX, você pode encontrar um sed: 1: "...": invalid command code .problema. Parece que a opção -i espera extensão e analisa o 's/../...'comando. Solução: passe a extensão '' para a opção -i sed -i '' 's/....
Robert Lujo
6
Nota: se você usar isso em um diretório e se perguntar por que svn stnão mostra alterações, é porque você modificou os arquivos nos diretórios .svn também! Use em find . -maxdepth 1 -type f -print0 | xargs -0 sed -i 's/toreplace/replaced/g'vez disso.
ACK_stoverflow 26/09/13
57
Além disso, tenha cuidado se você estiver em um repositório Git. Eu pensei que era inteligente testando isso em uma ramificação clara para que eu pudesse reverter se fizesse algo ruim, mas corrompeu meu índice git.
Ciryon 4/10
13
Use isso grep -r 'hello' -l --null . | xargs -0 sed -i 's#hello#world#g'para evitar a edição de arquivos não relacionados (o sed pode alterar a codificação do arquivo).
caiguanhao
6
"mas corrompeu meu índice git." Não se preocupe muito com isso, você pode apenas fazer find .git ... | ... 'sed -i s/(the opposite from before)/g'para corrigir o seu índice git
Massey101
259
Nota : Não execute este comando em uma pasta incluindo um repositório git - alterações em .git podem corromper seu índice git.
find /home/www/-type f -exec \
sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'{}+
Comparado a outras respostas aqui, isso é mais simples do que a maioria e usa sed em vez de perl, que é o que a pergunta original fazia.
Observe que, se você estiver usando o BSD sed (incluindo no Mac OS X), precisará fornecer uma sequência de argumentos vazia e explícita arg à -iopção do sed . ou seja: sed -i '' 's/original/replacement/g'
Nathan Craike 23/03
2
@JohnZwinck Meu erro, perdeu o +. Estranhamente, a solução da Nikita é mais rápida para mim.
Sam
6
@AoeAoe: Isso +reduz bastante o número de sedprocessos gerados. É mais eficiente.
John Zwinck
4
Como posso fazer isso com segurança em uma pasta com um repositório git?
24516 Hatshepsut
20
É seguro para executar em uma pasta que contém um repositório git se você excluir a repo de seus resultados da procura: find . -not -path '*/\.git*' -type f ....
Dale Anderson
210
A maneira mais simples para mim é
grep -rl oldtext .| xargs sed -i 's/oldtext/newtext/g'
@ Anatoly: apenas uma pergunta: como posso excluir arquivos binários (arquivos executáveis) ?
user2284570
3
@ user2284570 Use os sinalizadores -Iou --binary-file=without-matchgrep.
Zéychin 15/09/14
34
Isso funciona especialmente bem quando você precisa excluir diretórios, como com .svn. Por exemplo:grep -rl oldtext . --exclude-dir=.svn | xargs sed -i 's/oldtext/newtext/g'
phyatt 13/11/2015
11
brew install gnu-sede use gsedno OSX para evitar um mundo de dor.
1
1
caras por favor, atenção, se seu projeto é git versão, use este em vez disso: git grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'. não é nada legal f * ck up seu .gitdir
Paolo
61
Todos os truques são quase os mesmos, mas eu gosto deste:
find <mydir>-type f -exec sed -i 's/<string1>/<string2>/g'{}+
find <mydir>: procure no diretório
-type f:
O arquivo é do tipo: arquivo regular
-exec command {} +:
Essa variante da ação -exec executa o comando especificado nos arquivos selecionados, mas a linha de comandos é criada anexando cada nome de arquivo selecionado no final; o número total de invocações do comando será muito menor que o número de arquivos correspondentes. A linha de comando é construída da mesma maneira que o xargs cria suas linhas de comando. Somente uma instância de `{} 'é permitida dentro do comando. O comando é executado no diretório inicial.
@ I159 Esta resposta não é idêntica à de John Zwinck ?
Reinstate Monica Please
1
@ user2284570 O conceito de "arquivo binário" não está totalmente bem definido. Você pode usar o filecomando para tentar determinar o tipo de cada arquivo, mas as variações aleatórias em sua saída podem ser um pouco desconcertantes. A opção -I(aka --mime) ajuda um pouco, ou --mime-typese você tiver. O modo exato de refatorar essa linha única pura para fazer isso está lamentavelmente fora do escopo desta pequena caixa de comentários. Talvez poste uma pergunta separada se precisar de ajuda? (Talvez adicione um comentário com um link para ele aqui, então.) #
Tripleee 18/02/16
1
a resposta mais limpa! Obrigado mate
jukerok
39
cd /home/www && find .-type f -print0 |
xargs -0 perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'
Estou curioso, existe uma razão para usar -print0e em xargsvez de -execou -execdir?
1840 Philipp
4
Existe: from "man find": o comando especificado é executado uma vez para cada arquivo correspondido. Ou seja, se houver 2000 arquivos em / home / www, 'find ... -exec ...' resultará em 2000 invocações de perl; Considerando que 'encontrar ... | xargs ... 'invocará o perl apenas uma ou duas vezes (assumindo ARG_MAX com cerca de 32 K e tamanho médio de nome de arquivo 20).
Empregado Russian
2
@ Russo empregado: é por isso que você usaria find -exec command {} +- evita invocações excessivas do comando como xargs, mas sem o processo separado.
21926 John Zwinck
2
Em qual plataforma? A solução xargs é portátil, as invocações "mágicas" de "find ... -exec" que não invocam um subprocesso para cada arquivo encontrado.
Empregado Russian
4
@EmployedRussian, find -exec ... {} +é especificado no POSIX desde 2006.
sed -i ''-e 's/subdomainA/subdomainB/g' $(find /home/www/-type f)
NOTA : -i ''resolve o problema OSXsed: 1: "...": invalid command code .
NOTA : Se houver muitos arquivos para processar, você receberá Argument list too long. A solução alternativa - uso find -execou xargssolução descrita acima.
A workarounddeve ser a sintaxe preferida em todos os casos.
Reinstate Monica Please
1
O problema com a substituição de comando $(find...)é que não há como o shell manipular nomes de arquivos com espaços em branco ou outros metacaracteres do shell. Se você sabe que isso não é um problema, essa abordagem é adequada; mas temos muitas perguntas em que as pessoas não foram avisadas sobre esse problema ou não entenderam o aviso.
É uma boa idéia se você trabalha em um repositório git, pois não corre o risco de sobrescrever .git / contents (conforme relatado nos comentários para outra resposta).
mahemoff
1
Obrigado, eu uso-o como uma função bash refactor() { echo "Replacing $1 by $2 in all files in this git repository." git grep -lz $1| xargs -0 perl -i'' -pE "s/$1/$2/g" }Uso, por exemplo, para substituir 'word' por 'sword': refactor word sworddepois verifique o que ele fez git diff.
Paul Rougieux 18/12/19
16
Para reduzir os arquivos para recursivamente sed, você pode, greppara sua instância de string:
grep -rl <oldstring>/path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g
Se você executar, man grepnotará que também pode definir um--exlude-dir="*.git" sinalizador se desejar omitir a pesquisa nos diretórios .git, evitando problemas de índice git, como outros indicaram educadamente.
Levando você a:
grep -rl --exclude-dir="*.git"<oldstring>/path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g
Mais sensato usar git-grepa -zopção em conjunto com xargs -0.
gniourf_gniourf
git grepobviamente, só faz sentido em um gitrepositório. A substituição geral seria grep -r.
tripleee
@gniourf_gniourf Você pode explicar?
precisa saber é o seguinte
2
@PetrPeller: with -z, git-grepseparará os campos de saída por bytes nulos em vez de novas linhas; e com -0, xargslerá a entrada separada por bytes nulos, em vez de espaços em branco (e não fará coisas estranhas com aspas). Então, se você não quer o comando de pausa, se os nomes de arquivos contêm espaços, aspas ou outros personagens engraçados, o comando é: git grep -z -l 'original_text' | xargs -0 sed ....
precisa saber é o seguinte
10
find /home/www/-type f -exec perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'{}+
find /home/www/ -type f listará todos os arquivos em / home / www / (e seus subdiretórios). O sinalizador "-exec" indica ao find para executar o seguinte comando em cada arquivo encontrado.
é o comando executado nos arquivos (muitos de cada vez). O {}é substituído por nomes de arquivos. O +no final do comando diz findpara criar um comando para muitos nomes de arquivos.
De acordo com a findpágina do manual: "A linha de comando é construída da mesma maneira que o xargs cria suas linhas de comando."
Assim, é possível atingir seu objetivo (e manipular nomes de arquivos contendo espaços) sem usar xargs -0, ou -print0.
O Ack-grep é muito eficiente para encontrar arquivos relevantes. Esse comando substituiu ~ 145.000 arquivos com facilidade, enquanto outros demoraram tanto que eu mal podia esperar até que eles terminassem.
Um método direto, se você precisar excluir diretórios ( --exclude-dir=.svn) e também pode ter nomes de arquivos com espaços (usando 0Byte com grep -Zexargs -0
grep -rlZ oldtext .--exclude-dir=.svn | xargs -0 sed -i 's/oldtext/newtext/g'
grep -lr 'subdomainA.example.com' | while read file; do sed -i "s/subdomainA.example.com/subdomainB.example.com/g" "$file"; done
Eu acho que a maioria das pessoas não sabe que pode inserir algo em um "arquivo de leitura ao mesmo tempo" e evita esses argumentos desagradáveis -print0, enquanto preserva espaços nos nomes de arquivos.
A adição adicional de um echobefore antes do sed permite que você veja quais arquivos serão alterados antes de realmente fazê-lo.
O motivo -print0é útil: ele lida com casos que while readsimplesmente não conseguem lidar - uma nova linha é um caractere válido em um nome de arquivo Unix; portanto, para que seu código seja completamente robusto, ele também precisa lidar com esses nomes de arquivo. (Além disso, você quer read -revitar algumas traquinas POSIX comportamento legado no read.)
tripleee
Além disso, o sedé um não-op se não houver correspondências, portanto grepnão é realmente necessário; embora seja uma otimização útil para evitar a reescrita de arquivos que não contêm correspondências, se você tiver muitas delas ou desejar evitar a atualização desnecessária de carimbos de data nos arquivos.
Tripleee
5
Você pode usar o awk para resolver isso como abaixo,
Funciona em MacOs sem problemas! Todos os sedcomandos baseados falharam quando os binários foram incluídos, mesmo com as configurações específicas do osx.
Jankapunkt
Cuidado ... isso explodirá se algum dos arquivos findretornados tiver um espaço em seus nomes! É muito mais seguro usar while read: stackoverflow.com/a/9612560/1938956 #
Soren Bjornstad 15/02/19
5
Maneira mais simples de substituir ( todos os arquivos, diretório, recursivo )
find .-type f -not -path '*/\.*'-exec sed -i 's/foo/bar/g'{}+
Nota: Às vezes você pode precisar ignorar alguns arquivos ocultos, ou seja,.git , , pode usar o comando acima.
Se você deseja incluir arquivos ocultos, use
find .-type f -exec sed -i 's/foo/bar/g'{}+
Nos dois casos, a string fooserá substituída por uma nova stringbar
Oi @RikHic, boa dica - estava pensando em algo assim; Infelizmente, a formatação acima não deu certo :) Então, eu vou tentar com uma pré tag (não funciona) - então, com backticks de escape: sed -i 's/subdomainA/subdomainB/g'` grep -ril 'subdomainA' /home/www/*` - isso ainda não parece muito bom, mas deve sobreviver copypaste :) Saúde!
Sdaau
4
#!/usr/local/bin/bash -x
find */home/www -type f |while read files
do
sedtest=$(sed -n '/^/,/$/p'"${files}"| sed -n '/subdomainA/p')if["${sedtest}"]then
sed s'/subdomainA/subdomainB/'g "${files}">"${files}".tmp
mv "${files}".tmp "${files}"fidone
grep recursivamente para a sequência que você deseja substituir em um determinado caminho e utilize apenas o caminho completo do arquivo correspondente. (esse seria o $(grep 'string' 'pathname' -Rl).
(opcional) se você quiser fazer um pré-backup desses arquivos no diretório centralizado, talvez também possa usá-lo: cp -iv $(grep 'string' 'pathname' -Rl) 'centralized-directory-pathname'
depois disso, você pode editar / substituir à vontade, vimseguindo um esquema semelhante ao fornecido no link fornecido:
Um pouco da velha escola, mas isso funcionou no OS X.
Existem alguns truques:
• Editará apenas arquivos com extensão .slsno diretório atual
• .deve ser escapado para garantir sedque não os avalie como "qualquer caractere"
• ,é usado como seddelimitador em vez do usual/
Observe também que isso é para editar um modelo Jinja para passar um variableno caminho de um import(mas isso não é tópico).
Primeiro, verifique se o seu comando sed faz o que você deseja (isso imprimirá apenas as alterações no stdout, não os arquivos):
for file in $(find .-name *.sls -type f);do echo -e "\n$file: "; sed 's,foo\.bar,foo/bar/\"+baz+\"/,g' $file;done
Edite o comando sed conforme necessário, quando estiver pronto para fazer alterações:
for file in $(find .-name *.sls -type f);do echo -e "\n$file: "; sed -i '''s,foo\.bar,foo/bar/\"+baz+\"/,g' $file;done
Observe o comando -i ''in sed , eu não queria criar um backup dos arquivos originais (como explicado em Edições no local com sed no OS X ou no comentário de Robert Lujo nesta página).
mais um para `` *. [c | cc | cp | cpp | m | mm | h] ''
FractalSpace
2
Aqui está uma versão que deve ser mais geral que a maioria; não requer find(usando em duvez disso), por exemplo. Requer xargs, que é encontrado apenas em algumas versões do Plano 9 (como o 9front).
du -a | awk -F' ''{ print $2 }'| xargs sed -i -e 's/subdomainA\.example\.com/subdomainB.example.com/g'
Se você deseja adicionar filtros como extensões de arquivo, use grep:
du -a | grep "\.scala$"| awk -F' ''{ print $2 }'| xargs sed -i -e 's/subdomainA\.example\.com/subdomainB.example.com/g'
Os parênteses parecem supérfluos. Isso anteriormente tinha um erro de formatação que o tornava inutilizável (a renderização do Markdown consumia alguns caracteres do regex).
Tripleee
1
Usando a combinação de grepesed
for pp in $(grep -Rl looking_for_string)do
sed -i 's/looking_for_string/something_other/g'"${pp}"done
Tripleee @ Eu modifiquei isso um pouco. Nesse caso, a saída para a grep -Rl patternlista gerada por comando de arquivos em que o padrão está. Os arquivos não são lidos em forloop.
Pawel
Hã? Você ainda tem um forloop; se algum nome de arquivo retornado contiver espaço em branco, ele não funcionará corretamente, porque o shell simboliza a forlista de argumentos. Mas então você usa a variável de nome de arquivo sem aspas dentro do loop, portanto ela seria quebrada lá se você corrigisse isso. A correção desses erros restantes tornaria o seu idêntico à resposta do @ MadMan2064.
Tripleee
@ tripleeee sim, isso é verdade, eu perdi isso.
Pawel
1
Para substituir todas as ocorrências em um repositório git, você pode usar:
git ls-files -z | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'
Consulte Listar arquivos no repositório git local? para outras opções para listar todos os arquivos em um repositório. As -zopções dizem ao git para separar os nomes dos arquivos com um byte zero, o que garante que xargs(com a opção -0) possam separar os nomes de arquivos, mesmo que contenham espaços ou outros enfeites.
-path ./.git -prune -o
emfind . -path ./.git -prune -o -type f -name '*matchThisText*' -print0
antes de tubulação para xargsRespostas:
-print0
dizfind
para imprimir cada um dos resultados separados por um caractere nulo, em vez de uma nova linha. No caso improvável de o seu diretório ter arquivos com novas linhas nos nomes, isso ainda permitexargs
trabalhar nos nomes de arquivos corretos.\( -type d -name .git -prune \)
é uma expressão que pula completamente todos os diretórios nomeados.git
. Você pode expandi-lo facilmente, se você usa o SVN ou tem outras pastas que deseja preservar - basta comparar com mais nomes. É aproximadamente equivalente a-not -path .git
, mas mais eficiente, porque, em vez de verificar todos os arquivos no diretório, ignora-o completamente. O-o
depois é necessário por causa de como-prune
realmente funciona.Para mais informações, consulte
man find
.fonte
sed: 1: "...": invalid command code .
problema. Parece que a opção -i espera extensão e analisa o's/../...'
comando. Solução: passe a extensão '' para a opção -ised -i '' 's/...
.svn st
não mostra alterações, é porque você modificou os arquivos nos diretórios .svn também! Use emfind . -maxdepth 1 -type f -print0 | xargs -0 sed -i 's/toreplace/replaced/g'
vez disso.grep -r 'hello' -l --null . | xargs -0 sed -i 's#hello#world#g'
para evitar a edição de arquivos não relacionados (o sed pode alterar a codificação do arquivo).find .git ... | ... 'sed -i s/(the opposite from before)/g'
para corrigir o seu índice gitNota : Não execute este comando em uma pasta incluindo um repositório git - alterações em .git podem corromper seu índice git.
Comparado a outras respostas aqui, isso é mais simples do que a maioria e usa sed em vez de perl, que é o que a pergunta original fazia.
fonte
-i
opção do sed . ou seja:sed -i '' 's/original/replacement/g'
+
reduz bastante o número desed
processos gerados. É mais eficiente.find . -not -path '*/\.git*' -type f ...
.A maneira mais simples para mim é
fonte
-I
ou--binary-file=without-match
grep..svn
. Por exemplo:grep -rl oldtext . --exclude-dir=.svn | xargs sed -i 's/oldtext/newtext/g'
brew install gnu-sed
e usegsed
no OSX para evitar um mundo de dor.git grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'
. não é nada legal f * ck up seu.git
dirTodos os truques são quase os mesmos, mas eu gosto deste:
find <mydir>
: procure no diretório-type f
:-exec command {} +
:fonte
file
comando para tentar determinar o tipo de cada arquivo, mas as variações aleatórias em sua saída podem ser um pouco desconcertantes. A opção-I
(aka--mime
) ajuda um pouco, ou--mime-type
se você tiver. O modo exato de refatorar essa linha única pura para fazer isso está lamentavelmente fora do escopo desta pequena caixa de comentários. Talvez poste uma pergunta separada se precisar de ajuda? (Talvez adicione um comentário com um link para ele aqui, então.) #fonte
-print0
e emxargs
vez de-exec
ou-execdir
?find -exec command {} +
- evita invocações excessivas do comando como xargs, mas sem o processo separado.find -exec ... {} +
é especificado no POSIX desde 2006.Para mim, a solução mais fácil de lembrar é https://stackoverflow.com/a/2113224/565525 , ou seja:
NOTA :
-i ''
resolve o problema OSXsed: 1: "...": invalid command code .
NOTA : Se houver muitos arquivos para processar, você receberá
Argument list too long
. A solução alternativa - usofind -exec
ouxargs
solução descrita acima.fonte
workaround
deve ser a sintaxe preferida em todos os casos.$(find...)
é que não há como o shell manipular nomes de arquivos com espaços em branco ou outros metacaracteres do shell. Se você sabe que isso não é um problema, essa abordagem é adequada; mas temos muitas perguntas em que as pessoas não foram avisadas sobre esse problema ou não entenderam o aviso.Para quem usa o silver searcher (
ag
)Como o ag ignora as pastas / arquivos git / hg / svn por padrão, é seguro executar dentro de um repositório.
fonte
Um oneliner agradável como um extra. Usando git grep.
fonte
refactor() { echo "Replacing $1 by $2 in all files in this git repository." git grep -lz $1| xargs -0 perl -i'' -pE "s/$1/$2/g" }
Uso, por exemplo, para substituir 'word' por 'sword':refactor word sword
depois verifique o que ele fezgit diff
.Para reduzir os arquivos para recursivamente
sed
, você pode,grep
para sua instância de string:Se você executar,
man grep
notará que também pode definir um--exlude-dir="*.git"
sinalizador se desejar omitir a pesquisa nos diretórios .git, evitando problemas de índice git, como outros indicaram educadamente.Levando você a:
fonte
Este é compatível com os repositórios git e um pouco mais simples:
Linux:
Mac:
(Obrigado a http://blog.jasonmeridth.com/posts/use-git-grep-to-replace-strings-in-files-in-your-git-repository/ )
fonte
git-grep
a-z
opção em conjunto comxargs -0
.git grep
obviamente, só faz sentido em umgit
repositório. A substituição geral seriagrep -r
.-z
,git-grep
separará os campos de saída por bytes nulos em vez de novas linhas; e com-0
,xargs
lerá a entrada separada por bytes nulos, em vez de espaços em branco (e não fará coisas estranhas com aspas). Então, se você não quer o comando de pausa, se os nomes de arquivos contêm espaços, aspas ou outros personagens engraçados, o comando é:git grep -z -l 'original_text' | xargs -0 sed ...
.find /home/www/ -type f
listará todos os arquivos em / home / www / (e seus subdiretórios). O sinalizador "-exec" indica ao find para executar o seguinte comando em cada arquivo encontrado.é o comando executado nos arquivos (muitos de cada vez). O
{}
é substituído por nomes de arquivos. O+
no final do comando dizfind
para criar um comando para muitos nomes de arquivos.De acordo com a
find
página do manual: "A linha de comando é construída da mesma maneira que o xargs cria suas linhas de comando."Assim, é possível atingir seu objetivo (e manipular nomes de arquivos contendo espaços) sem usar
xargs -0
, ou-print0
.fonte
Eu só precisava disso e não estava satisfeito com a velocidade dos exemplos disponíveis. Então eu criei o meu próprio:
O Ack-grep é muito eficiente para encontrar arquivos relevantes. Esse comando substituiu ~ 145.000 arquivos com facilidade, enquanto outros demoraram tanto que eu mal podia esperar até que eles terminassem.
fonte
grep -ril 'subdomainA' *
não é nem de longe tão rápido quantogrep -Hr 'subdomainA' * | cut -d: -f1
.Um método direto, se você precisar excluir diretórios (
--exclude-dir=.svn
) e também pode ter nomes de arquivos com espaços (usando 0Byte comgrep -Z
exargs -0
fonte
grep -lr 'subdomainA.example.com' | while read file; do sed -i "s/subdomainA.example.com/subdomainB.example.com/g" "$file"; done
Eu acho que a maioria das pessoas não sabe que pode inserir algo em um "arquivo de leitura ao mesmo tempo" e evita esses argumentos desagradáveis -print0, enquanto preserva espaços nos nomes de arquivos.
A adição adicional de um
echo
before antes do sed permite que você veja quais arquivos serão alterados antes de realmente fazê-lo.fonte
-print0
é útil: ele lida com casos quewhile read
simplesmente não conseguem lidar - uma nova linha é um caractere válido em um nome de arquivo Unix; portanto, para que seu código seja completamente robusto, ele também precisa lidar com esses nomes de arquivo. (Além disso, você querread -r
evitar algumas traquinas POSIX comportamento legado noread
.)sed
é um não-op se não houver correspondências, portantogrep
não é realmente necessário; embora seja uma otimização útil para evitar a reescrita de arquivos que não contêm correspondências, se você tiver muitas delas ou desejar evitar a atualização desnecessária de carimbos de data nos arquivos.Você pode usar o awk para resolver isso como abaixo,
espero que isso ajude você !!!
fonte
sed
comandos baseados falharam quando os binários foram incluídos, mesmo com as configurações específicas do osx.find
retornados tiver um espaço em seus nomes! É muito mais seguro usarwhile read
: stackoverflow.com/a/9612560/1938956 #Maneira mais simples de substituir ( todos os arquivos, diretório, recursivo )
Nota: Às vezes você pode precisar ignorar alguns arquivos ocultos, ou seja,
.git
, , pode usar o comando acima.Se você deseja incluir arquivos ocultos, use
Nos dois casos, a string
foo
será substituída por uma nova stringbar
fonte
Tente o seguinte:
fonte
sed -i 's/subdomainA/subdomainB/g'
`grep -ril 'subdomainA' /home/www/*
` - isso ainda não parece muito bom, mas deve sobreviver copypaste :) Saúde!fonte
De acordo com este post do blog:
fonte
/
? Por exemplo, eu quero substituir endereços IP:xxx.xxx.xxx.xxx
forxxx.xxx.xxx.xxx/folder
/
com \. Por exemplo:find . -type f | xargs perl -pi -e 's/xxx.xxx.xxx.xxx\/folder/newtext/g;'
Se você não se importa de usar
vim
junto comgrep
oufind
ferramentas, pode acompanhar a resposta dada pelo usuário Gert neste link -> Como fazer uma substituição de texto em uma hierarquia de pastas grandes? .Aqui está o acordo:
grep recursivamente para a sequência que você deseja substituir em um determinado caminho e utilize apenas o caminho completo do arquivo correspondente. (esse seria o
$(grep 'string' 'pathname' -Rl)
.(opcional) se você quiser fazer um pré-backup desses arquivos no diretório centralizado, talvez também possa usá-lo:
cp -iv $(grep 'string' 'pathname' -Rl) 'centralized-directory-pathname'
depois disso, você pode editar / substituir à vontade,
vim
seguindo um esquema semelhante ao fornecido no link fornecido::bufdo %s#string#replacement#gc | update
fonte
Um pouco da velha escola, mas isso funcionou no OS X.
Existem alguns truques:
• Editará apenas arquivos com extensão
.sls
no diretório atual•
.
deve ser escapado para garantirsed
que não os avalie como "qualquer caractere"•
,
é usado comosed
delimitador em vez do usual/
Observe também que isso é para editar um modelo Jinja para passar um
variable
no caminho de umimport
(mas isso não é tópico).Primeiro, verifique se o seu comando sed faz o que você deseja (isso imprimirá apenas as alterações no stdout, não os arquivos):
Edite o comando sed conforme necessário, quando estiver pronto para fazer alterações:
Observe o comando
-i ''
in sed , eu não queria criar um backup dos arquivos originais (como explicado em Edições no local com sed no OS X ou no comentário de Robert Lujo nesta página).Gente sedutora feliz!
fonte
só para evitar mudar também
mas ainda
(talvez não seja bom na idéia por trás da raiz do domínio)
fonte
Eu apenas uso tops:
fonte
Aqui está uma versão que deve ser mais geral que a maioria; não requer
find
(usando emdu
vez disso), por exemplo. Requerxargs
, que é encontrado apenas em algumas versões do Plano 9 (como o 9front).Se você deseja adicionar filtros como extensões de arquivo, use
grep
:fonte
Para Qshell (qsh) no IBMi, não faça o bash conforme marcado pelo OP.
Limitações dos comandos qsh:
Assim, a solução em qsh:
Ressalvas:
fonte
for
.Se você quiser usar isso sem destruir completamente o seu repositório SVN, poderá dizer a 'find' para ignorar todos os arquivos ocultos, fazendo:
fonte
Usando a combinação de
grep
esed
fonte
grep -Rl pattern
lista gerada por comando de arquivos em que o padrão está. Os arquivos não são lidos emfor
loop.for
loop; se algum nome de arquivo retornado contiver espaço em branco, ele não funcionará corretamente, porque o shell simboliza afor
lista de argumentos. Mas então você usa a variável de nome de arquivo sem aspas dentro do loop, portanto ela seria quebrada lá se você corrigisse isso. A correção desses erros restantes tornaria o seu idêntico à resposta do @ MadMan2064.Para substituir todas as ocorrências em um repositório git, você pode usar:
Consulte Listar arquivos no repositório git local? para outras opções para listar todos os arquivos em um repositório. As
-z
opções dizem ao git para separar os nomes dos arquivos com um byte zero, o que garante quexargs
(com a opção-0
) possam separar os nomes de arquivos, mesmo que contenham espaços ou outros enfeites.fonte
fonte
awk
/sed
, mas o perl é comum (exceto sistemas / embarcados apenas com o busybox).para alterar vários arquivos (e salvar um backup como
*.bak
):pegará todos os arquivos no diretório e substituirá
|
por x chamado “torta Perl” (fácil como torta)fonte