Ersetze einen String in allen Beiträgen

: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 „Gefällt mir“

Wie würde ich das nur für die Themen in einer einzigen Kategorie tun?

Mein Anwendungsfall ist ein importierter RSS-Feed, der ärgerlicherweise ein ? anstelle eines ' anzeigt. Da es sich bei dem Feed um einen Nachrichten-Feed mit vielen Anführungszeichen handelt, ist dies ein Problem!

1 „Gefällt mir“

Das würdest du von Rails aus machen, und es wird schwierig sein, da Beiträge nicht zu Kategorien gehören, sondern Themen. Es klingt, als ob du ein Plugin brauchst, wenn dies ein fortlaufendes Problem ist. Du könntest clever mit einem Join sein oder einfach so loopen:

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

Wenn es nicht nur in post_number: ist, schließe das nicht ein.

Wenn es keine riesige Anzahl von Beiträgen ist, dann ist das wahrscheinlich gut genug, wenn es überhaupt funktioniert.

1 „Gefällt mir“

Danke Jay! Das würde den Zweck gut erfüllen.

Ich muss es richtig untersuchen und sehen, ob es eine Lösung auf höherer Ebene gibt. Oder ich muss etwas an das RSS Polling Plugin anhängen, was ein ziemlich kniffliges Biest ist!

1 „Gefällt mir“

Nur eine Vermutung, aber treten bei Beiträgen, die aus dem RSS-Feed erstellt wurden, auch andere Probleme auf? Sind die ?-Zeichen vorhanden, wenn Sie die Quellansicht des Feeds anzeigen? Ich frage mich, ob Sie auf ein Kodierungsproblem stoßen.

2 „Gefällt mir“

Ja, das sehe ich mir gerade an. Die ? sind jedes Mal da, wenn ein ungewöhnliches Zeichen vorkommt, also liegt das Problem am RSS-Quell-Ende. Es stellt sich heraus, dass ' nur das häufigste ist, aber es passiert auch für ā, \" und ein oder zwei andere.

Leider ist die beteiligte Softwarefirma nicht ganz so reaktionsschnell wie das Discourse-Team :kissing_heart:! Wünschen Sie mir Glück.

2 „Gefällt mir“

Das habe ich auch vermutet. Es könnte so einfach sein wie eine bessere Erkennung der richtigen Kodierung.

3 „Gefällt mir“

Gibt es eine Anleitung, wie ich das wie folgt ersetzen kann?

[member=12345] → @

Ich habe dieses Beispiel verwendet, das zum Ersetzen einer URL funktioniert. Es funktioniert jedoch nicht für Phrasen.

Beispiel:

rake posts:remap["Ich möchte diese Phrase nicht","Aber ich möchte diese eine","string",true]

Ich erhalte immer diesen Fehler:

ERROR: Erwarte rake posts:remap['find','replace',type], wobei type string oder regex ist

Ich habe es auch mit den einfachen Anführungszeichen versucht, wie in der Fehlermeldung gezeigt, aber ohne Erfolg. Ich habe sogar versucht, Bindestriche zwischen die Wörter zu setzen, wie im Beispiel zum Löschen von Wörtern. Das gab mir denselben Fehler.

Irgendein Rat?

Ich befürchte, wenn Sie etwas mit Anführungszeichen tun müssen, ist es am besten, dies in Rails zu tun. Mit der Rake-Aufgabe müssen Sie sich sowohl mit bash als auch mit Rails zum Escapen befassen. Möglicherweise können Sie eine Reihe von Backslashes verwenden (die ebenfalls escaped werden müssen), aber wahrscheinlich nicht.

Schauen Sie sich das Rails-Beispiel an, das ich oben habe, und sehen Sie, ob das Sinn ergibt. Ich werde dem OP etwas hinzufügen, wenn ich das nächste Mal einen Laptop habe.

1 „Gefällt mir“

Vielen Dank für die Antwort. Das übersteigt meine Kenntnisse, aber ich kann auf jeden Fall lernen.

Es scheint, dass die Anführungszeichen in der Textzeichenfolge mein Problem verursacht haben…

Mein Zweck ist es, Titel und URLs meines Blogs zu ändern. Daher gehe ich gerne zum Forum zurück und aktualisiere diese Links, die Titel und URLs ebenfalls. Ich kann mir vorstellen, dass dies eine halbwegs regelmäßige Aufgabe sein wird, wenn ich an SEO arbeite. Weitere Details wären fantastisch.

1 „Gefällt mir“

Hier muss ich etwas übersehen. Ich versuche, Vorkommen von :THUMBS-UP: durch :+1: in fast 3 Millionen Beiträgen (einschließlich PMs) zu ersetzen. Ich habe Folgendes ausgeführt:
rake posts:remap[\":THUMBS-UP:\",\":+1:\"]
Und nach etwa 50 Minuten ................. gab es 40000 posts remapped! zurück. Das scheint eine verdächtig glatte Zahl zu sein. Ich habe einige Vorkommen gefunden, die sowohl in neueren Beiträgen als auch in Beiträgen von vor vielen Jahren durch :+1: ersetzt wurden, aber es gibt auch eine Menge von :THUMBS-UP: sogar in denselben Thread-Themen, die auch einige erfolgreiche :+1:-Ersetzungen aufweisen.

Das erscheint mir doch etwas seltsam. Hast du versucht, es erneut zuzuordnen?
Du kannst auch ganz einfach die Anzahl der Beiträge, die noch :THUMBS-UP: enthalten, mit dem Daten-Explorer zurückgeben, falls diese Information von Nutzen sein kann.

Ja, das ist seltsam. Ich habe versucht, denselben Befehl dreimal mehr auszuführen, und jedes Mal wurden 333 weitere Beiträge neu zugeordnet… :question:

Im Log werden eine Menge angeblicher Ersetzungen angezeigt, außer dass die tatsächlichen Beiträge, wenn ich die Seite neu lade und inspiziere, unverändert bleiben:

Das schien mir ein Caching-Problem zu sein, also habe ich redis-cli flushall ausgeführt und Discourse hart neu geladen, aber immer noch keine Änderung an den Beiträgen, die im Log als bearbeitet gemeldet wurden.

Und auch im Fehlerprotokoll eine Menge Meldungen wie diese:
Screenshot from 2023-01-06 12-47-36

Das sollte in Ordnung sein … aber eines der Probleme ist, dass es so aussieht, als ob man andere Dinge wie Kommas zitieren könnte, aber das kann man nicht, da die Anführungszeichen vom Shell verbraucht werden, nicht vom Rake-Parser.

z.B.:

→ rake posts:remap["a,b","a+b"]
FEHLER: Erwarte rake posts:remap['find','replace',type], wobei type string oder regex ist

Und die Klammern sollten zitiert werden, da sie selbst Shell-Metazeichen sind. Sie können den Befehl nicht einmal mit einer Datei namens posts:remapa im Verzeichnis (so unwahrscheinlich dies auch sein mag) oder mit gesetztem failglob ausführen.

Ich denke, wir sollten diese Befehle ändern - sie sind irreführend in dem Sinne, dass sie so aussehen, als ob man die zu ersetzenden Zeichenfolgen zitiert, aber das tun wir wirklich nicht. Die Anführungszeichen werden von der Shell verbraucht; Rails sieht sie nie. Es gibt keinen Grund, die Anführungszeichen überhaupt zu haben, und wenn Rails sie sieht, sind sie Teil der Zeichenfolge:

→ rake 'posts:remap["find","replace"]'
Sind Sie sicher, dass Sie alle Zeichenfolgenvorkommen von '"find"' durch '"replace"' ersetzen möchten? (J/n)

Einige weitere Beispiele, einschließlich des Umgangs mit Dingen wie Kommas, sind:

rake 'posts:remap[find,replace,string,true]'
rake $'posts:remap[string with a quote\\',string without a quote]'
rake 'posts:remap[a\\, b,a+b]'

obwohl dies merkwürdigerweise funktioniert:

→ rake 'posts:remap[string with a bracket] either quoted\] or not,string without a bracket]'
Sind Sie sicher, dass Sie alle Zeichenfolgenvorkommen von 'string with a bracket] either quoted] or not' durch 'string without a bracket' ersetzen möchten? (J/n)
1 „Gefällt mir“

Ist es möglich, dass der Rohinhalt geändert wurde, der (neue) Beitrag aber noch nicht fertiggestellt ist?

Ich habe auch darüber nachgedacht, aber nein, ich habe auf den Bearbeiten-Button bei diesen Beiträgen geklickt und der Rohinhalt ist unverändert. Und bei den erfolgreichen Ersetzungen erscheint das neue Emoji ohne erneutes Backen.

1 „Gefällt mir“

Ich versuche, über 600 Instanzen von importierten YouTube-Links zu ersetzen, aber es scheint nur zu funktionieren, wenn sie allein in einer Zeile stehen.

Ich muss also einen Zeilenumbruch vor dem YouTube-Link selbst einfügen. Glücklicherweise habe ich einen “replaceme”-String, der durch den Zeilenumbruch ersetzt werden kann.

Ist der richtige Weg ein Ruby-Zeilenumbruch? Oder ein Markdown-Zeilenumbruch?

Würde so etwas funktionieren?

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

Oder muss ich das \n mehrmals escapen?

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

Oder sollte ich auf den Markdown-Zeilenumbruch abzielen (der ein einzelner Backslash ist, richtig?):

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

Ich schätze, das müsste ich auch escapen?

Jede Anleitung wird geschätzt.

Ich würde es in Rails machen, wo man sich nicht um so viele Anführungszeichen kümmern muss.

2 „Gefällt mir“

Gute Idee. Das Maskieren von Dingen bereitet mir Kopfzerbrechen.

Ich sehe, dass Ihr obiger Code einfach genug ist. So etwas?

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

So etwas? Ich nehme an, das Markdown / ist besser als die Verwendung von CR/LF oder \n, oder sogar \u003cbr /\u003e oder was auch immer?

Wie führt man das von der Shell aus? Tippt man einfach “rails” ein und kopiert dann den Code hinein?