Substituir uma string em todas as postagens

:bookmark: This guide explains how to replace a string in all posts within a Discourse instance.

:person_raising_hand: Required user level: System Administrator

:warning: Console Access Required

Want to replace a string in all the posts on a site? Let’s get started!

:warning: WARNING: We strongly recommend you take a full backup before proceeding, and make sure your string replacement is specific enough to affect only the places you want it to. If this string replacement goes wrong, every post on your site will look broken!

Access your site

Start by accessing your Discourse instance via SSH and entering the Docker container:

cd /var/discourse
./launcher enter app

Performing string replacements

Basic case-sensitive replacement

To replace a string, use the following command. Replace find with the string to locate and replace with the desired substitution:

rake 'posts:remap[find,replace]'

Example results:

find —> replace
Find —> Find
FIND —> FIND
finders keepers —> replaceers keepers
finding —> replaceing

This method can be useful for tasks such as replacing emojis:

rake 'posts:remap[:slightly_smiling:,:slight_smile:]'

The above command will replace all occurrences of :slightly_smiling: with :slight_smile:.

Case-insensitive replacement

For replacements that ignore case sensitivity use:

rake 'posts:remap[find,replace,string,true]'

Example results:

find —> replace
Find —> replace
FIND —> replace
finders keepers —> replaceers keepers
finding —> replaceing

Regex replacement

For advanced replacements with regex, format the command accordingly:

rake 'posts:remap[(?<!\\w)(?=\\w)find(?<=\\w)(?!\\w),replace,regex]'

Example results:

replace —> replace
Find —> Find
FIND —> FIND
finders keepers —> finders keepers
finding —> finding

Deleting words or strings

To completely remove a word or string, apply these commands:

Basic case-sensitive deletion

rake 'posts:delete_word[word-to-delete]'

Case-insensitive deletion

rake 'posts:delete_word[word-to-delete,string,true]'

Regex deletion

rake 'posts:delete_word[\\[color=#[0-9a-fA-F]{3,6}\\],regex]'

Last edited by @SaraDev 2024-11-14T00:39:05Z

Check documentPerform check on document:
70 curtidas

Como eu faria isso apenas para os tĂłpicos em uma Ășnica categoria?

Meu caso de uso é um feed RSS importado que, irritantemente, exibe um ? em vez de um '. E como o feed é um feed de notícias com muitas citaçÔes, isso é um problema!

1 curtida

VocĂȘ faria isso a partir do Rails, e serĂĄ difĂ­cil porque as postagens nĂŁo pertencem a categorias, os tĂłpicos sim. Parece que vocĂȘ precisa de um plugin se este for um problema contĂ­nuo. VocĂȘ poderia ser inteligente com um join ou apenas fazer um loop como

Topics.where(category_id: 123).each do |t|
  posts.where(topic_id: t, post_number: 1).each do |p|
    if p.raw.match("\?")
        p.raw.gsub!("\?","'")
        p.save
    end
  end
end

Se nĂŁo for apenas em post_number: , nĂŁo inclua isso.

Se nĂŁo for um grande nĂșmero de postagens, entĂŁo isso provavelmente Ă© bom o suficiente, se Ă© que funciona.

1 curtida

Obrigado, Jay! Isso resolveria o problema perfeitamente.

Preciso mesmo solucionar isso corretamente e ver se hå uma correção upstream. Ou talvez eu precise adicionar algo ao Plugin de Pesquisa RSS, que é uma fera um tanto complicada!

1 curtida

Apenas um palpite, mas vocĂȘ estĂĄ vendo algum outro problema com posts criados a partir do feed RSS? Os caracteres ? estĂŁo presentes quando vocĂȘ visualiza a origem do feed? Estou me perguntando se o que vocĂȘ estĂĄ encontrando Ă© um problema de codificação.

2 curtidas

Sim, estou vendo isso agora. Os ? estão lå sempre que hå um caractere incomum, então é um problema na origem do RSS. Acontece que ' é apenas o mais comum, mas também estå acontecendo com ā, \" e um ou dois outros.

Infelizmente, a empresa de software envolvida nĂŁo Ă© tĂŁo responsiva quanto a equipe do Discourse :kissing_heart:! Deseje-me sorte.

2 curtidas

Era isso que eu também estava suspeitando. Pode ser tão simples quanto detectar melhor a codificação correta.

3 curtidas

Alguma orientação para substituir como abaixo, por favor?

[member=12345] → @

Usei este exemplo que funciona para substituir um URL. No entanto, nĂŁo estĂĄ funcionando para frases.

Exemplo:

rake posts:remap["Eu NĂŁo Quero Esta Frase","Mas Eu Quero Esta Outra","string",true]

Continuo recebendo este erro:

ERROR: Expecting rake posts:remap['find','replace',type] where type is string or regex

Tentei com as aspas simples como mostrado na mensagem de erro, mas sem sucesso. Até tentei colocar hifens entre as palavras, como no exemplo de exclusão de palavras. Isso deu o mesmo erro.

Algum conselho?

Receio que, se vocĂȘ precisar fazer algo com aspas, Ă© melhor fazĂȘ-lo no Rails. Com a tarefa do Rake, vocĂȘ tem que lidar tanto com bash quanto com o Rails para escapar. VocĂȘ pode ser capaz de usar um monte de barras invertidas (que tambĂ©m precisam ser escapadas), mas provavelmente nĂŁo.

DĂȘ uma olhada no exemplo do Rails que tenho acima e veja se faz sentido. Tentarei adicionar algo ao OP na prĂłxima vez que tiver um laptop.

1 curtida

Obrigado pela resposta. Isso parece estar acima do meu nĂ­vel, mas com certeza posso aprender.

Parece que as aspas na string de texto foram o que causaram meu problema


Meu propósito é que eu me vejo mudando títulos e URLs do meu blog, então gosto de voltar ao fórum e atualizar esses links, os títulos e as URLs também. Posso ver isso como uma tarefa semi-regular quando estou trabalhando em SEO. Quaisquer detalhes adicionais seriam fantåsticos.

1 curtida

Deve haver algo que nĂŁo estou entendendo aqui. Estou tentando substituir ocorrĂȘncias de :THUMBS-UP: por :+1: em quase 3 milhĂ”es de posts (incluindo mensagens privadas). Eu executei:
rake posts:remap[":THUMBS-UP:",":+1:"]
E depois de cerca de 50 minutos de ................. ele retornou 40000 posts remapped! Este parece um nĂșmero suspeitosamente redondo. Eu encontrei algumas ocorrĂȘncias que foram substituĂ­das por :+1: tanto em posts recentes quanto em posts de muitos anos atrĂĄs, mas tambĂ©m hĂĄ um monte de :THUMBS-UP: mesmo nos mesmos tĂłpicos que tambĂ©m tĂȘm algumas substituiçÔes bem-sucedidas de :+1:.

Isso parece um pouco estranho. VocĂȘ tentou remapear novamente?
VocĂȘ tambĂ©m pode retornar facilmente o nĂșmero de posts que ainda contĂȘm :THUMBS-UP: usando o data-explorer, se essa informação puder ser Ăștil.

Sim, Ă© estranho. Eu tentei executar o mesmo comando dois trĂȘs vezes mais, e cada vez ele remapeou mais 333 posts
 :question:

No log, ele estå mostrando um monte de supostas substituiçÔes, exceto que quando eu recarrego a pågina e inspeciono o post real, ele permanece inalterado:

Isso me pareceu um problema de cache, então eu fiz um redis-cli flushall e recarreguei o Discourse forçadamente, mas ainda nenhuma mudança nos posts que foram relatados como editados no log.

E também no log de erros, um monte de mensagens como esta:
Screenshot from 2023-01-06 12-47-36

Isso deve funcionar
 mas um dos problemas Ă© que parece que vocĂȘ pode citar outras coisas, como vĂ­rgulas, mas nĂŁo pode, jĂĄ que as aspas sĂŁo consumidas pelo shell, nĂŁo pelo parser do rake.

por exemplo:

→ rake posts:remap["a,b","a+b"]
ERRO: Esperado rake posts:remap['encontrar','substituir',tipo] onde tipo Ă© string ou regex

E os colchetes devem ser citados, pois sĂŁo metacaracteres do shell. VocĂȘ nem conseguirĂĄ executar o comando com um arquivo chamado posts:remapa no diretĂłrio (por mais improvĂĄvel que isso seja) ou com failglob definido.

Eu acho que deverĂ­amos mudar esses comandos - eles sĂŁo enganosos no sentido de que parecem que vocĂȘ estĂĄ citando as strings que estĂŁo sendo substituĂ­das, mas na verdade nĂŁo estamos. As aspas sĂŁo consumidas pelo shell; o rails nunca as vĂȘ. NĂŁo hĂĄ razĂŁo para ter as aspas, e se o rails as vir, elas farĂŁo parte da string:

→ rake 'posts:remap["find","replace"]'
VocĂȘ tem certeza que deseja substituir todas as ocorrĂȘncias de string de '"find"' por '"replace"'? (S/n)

Alguns exemplos adicionais, incluindo como lidar com coisas como vĂ­rgulas, sĂŁo:

rake 'posts:remap[find,replace,string,true]'
rake $'posts:remap[string com uma aspa\\',string sem aspa]'
rake 'posts:remap[a\\, b,a+b]'

embora, curiosamente, isso funcione:

→ rake 'posts:remap[string com um colchete] seja citado\] ou não,string sem um colchete]'
VocĂȘ tem certeza que deseja substituir todas as ocorrĂȘncias de string de 'string com um colchete] seja citado] ou nĂŁo' por 'string sem um colchete'? (S/n)
1 curtida

É possível que o texto bruto tenha sido alterado, mas a (nova) postagem ainda não foi processada?

Eu tambĂ©m pensei nisso, mas nĂŁo, eu cliquei no botĂŁo de editar nessas postagens e o cĂłdigo bruto nĂŁo foi alterado. E nas substituiçÔes bem-sucedidas, o novo emoji aparece sem um “rebake”.

1 curtida

EntĂŁo, estou tentando substituir mais de 600 instĂąncias de links importados do YouTube, mas parece que sĂł funciona quando estĂĄ em uma linha prĂłpria.

Então, preciso inserir uma nova linha antes do próprio link do YouTube. Felizmente, tenho uma string do tipo “replaceme” que pode ser substituída pela nova linha.

A maneira apropriada de fazer uma nova linha em Ruby? Ou uma nova linha em Markdown?

Algo assim funcionaria?

rake posts:remap["replaceme","\n",string,true]

Ou preciso escapar o \n algumas vezes?

rake posts:remap["replaceme","\\\n",string,true]

Ou devo mirar na nova linha do markdown (que Ă© uma Ășnica barra invertida, correto?):

rake posts:remap["replaceme","\",string,true]

Acho que também teria que escapar isso?

Qualquer orientação é apreciada.

Eu faria isso no Rails, onde vocĂȘ nĂŁo precisa se preocupar com tantos nĂ­veis de citação.

2 curtidas

Boa ideia. Escapar coisas faz minha cabeça doer.

Vejo que seu cĂłdigo acima Ă© simples o suficiente. Algo como isto?

Topics.where(category_id: 123).each do |t|
  posts.where(topic_id: t).each do |p|
    p.raw.gsub("replaceme","/")
  end
end

Algo assim? Presumo que a barra de markdown / seja melhor do que usar CR/LF ou \n, ou mesmo \u003cbr /\u003e ou o que quer que seja?

Como se executa isso do shell? Basta digitar “rails” e depois colar o código lá?