إستبدال نص في جميع المنشورات

: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 إعجابًا

كيف يمكنني فعل ذلك للمواضيع الموجودة في فئة واحدة فقط؟

حالة الاستخدام الخاصة بي هي موجز RSS مستورد والذي يعرض بشكل مزعج علامة ؟ بدلاً من علامة '. وبما أن الموجز هو موجز إخباري يحتوي على الكثير من الاقتباسات، فهذه مشكلة!

إعجاب واحد (1)

ستفعل ذلك من خلال Rails، وسيكون الأمر صعبًا لأن المشاركات لا تنتمي إلى فئات، بل المواضيع تنتمي إليها. يبدو أنك بحاجة إلى إضافة (plugin) إذا كانت هذه مشكلة مستمرة. يمكنك أن تكون ذكيًا باستخدام join أو مجرد التكرار مثل

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

إذا لم يكن فقط في post_number: ، فلا تقم بتضمين ذلك.

إذا لم يكن عدد المشاركات كبيرًا، فهذا على الأرجح جيد بما فيه الكفاية، إذا كان يعمل على الإطلاق.

إعجاب واحد (1)

شكرا جاي! هذا سيحل المشكلة بشكل جيد.

أحتاج إلى استكشاف المشكلة وإصلاحها بشكل صحيح ومعرفة ما إذا كان هناك حل في المصدر. أو قد أحتاج إلى إضافة شيء ما إلى إضافة استطلاع RSS وهي مشكلة صعبة بعض الشيء!

إعجاب واحد (1)

مجرد تخمين، ولكن هل ترى أي مشاكل أخرى مع المشاركات التي تم إنشاؤها من موجز RSS؟ هل توجد أحرف ؟ عند عرض مصدر الموجز؟ أتساءل عما إذا كانت المشكلة التي تواجهها هي مشكلة ترميز.

إعجابَين (2)

نعم، أنا أنظر إلى هذا الآن. توجد علامات ؟ في كل مرة يكون هناك حرف غير عادي، لذا فهي مشكلة في نهاية مصدر RSS. اتضح أن ' هو الأكثر شيوعًا، ولكنه يحدث أيضًا لـ ā و \" وواحد أو اثنين آخرين.

لسوء الحظ، شركة البرمجيات المعنية ليست سريعة الاستجابة مثل فريق Discourse :kissing_heart:! تمنوا لي حظًا موفقًا.

إعجابَين (2)

هذا ما كنت أشك فيه أيضًا. قد يكون الأمر بسيطًا مثل اكتشاف الترميز الصحيح بشكل أفضل.

3 إعجابات

أي إرشادات للاستبدال كما يلي من فضلك؟

[member=12345] → @

لقد استخدمت هذا المثال الذي يعمل على استبدال عنوان URL. ومع ذلك، فإنه لا يعمل مع العبارات.

مثال:

rake posts:remap["I Don't Want This Phrase","But I Do Want This One","string",true]

ما زلت أتلقى هذا الخطأ:

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

لقد جربت ذلك باستخدام علامات الاقتباس المفردة كما هو موضح في رسالة الخطأ أيضًا، ولكن دون جدوى. لقد جربت حتى وضع شرطات بين الكلمات كما في مثال حذف الكلمة. أعطاني نفس الخطأ.

أي نصائح؟

أخشى أنه إذا كنت بحاجة إلى القيام بشيء ما مع الاقتباسات، فمن الأفضل القيام بذلك في rails. مع مهمة rake، عليك التعامل مع كل من bash و rails للهروب. قد تتمكن من استخدام مجموعة من الشرطات المائلة العكسية (التي تحتاج أيضًا إلى الهروب)، ولكن ربما لا.\n\nألقِ نظرة على مثال rails الذي قدمته أعلاه وانظر ما إذا كان ذلك منطقيًا. سأحاول إضافة شيء إلى OP في المرة القادمة التي أحصل فيها على جهاز كمبيوتر محمول.

إعجاب واحد (1)

شكراً على الرد. يبدو هذا فوق قدراتي، لكن يمكنني بالتأكيد التعلم.
يبدو أن علامات الاقتباس في سلسلة النص هي ما تسبب في مشكلتي…
هدفي، أجد نفسي أغير عناوين وروابط مدونتي، لذلك أحب العودة إلى المنتدى وتحديث تلك الروابط، والعناوين والروابط أيضًا. يمكنني رؤية أن هذه مهمة شبه منتظمة عندما أعمل على تحسين محركات البحث. أي تفاصيل إضافية ستكون رائعة.

إعجاب واحد (1)

يبدو أن هناك شيئًا لا أفهمه هنا. أحاول استبدال تكرارات :THUMBS-UP: بـ :+1: عبر ما يقرب من 3 ملايين منشور (بما في ذلك الرسائل الخاصة). قمت بتشغيل:
rake posts:remap[":THUMBS-UP:",":+1:"]
وبعد حوالي 50 دقيقة من ................. أعادت 40000 posts remapped! هذا يبدو رقمًا زوجيًا مثيرًا للريبة. لقد وجدت بعض التكرارات التي تم استبدالها بـ :+1: في المنشورات الحديثة والمنشورات منذ سنوات عديدة، ولكن هناك أيضًا الكثير من :THUMBS-UP: حتى في نفس سلاسل الموضوعات التي تحتوي أيضًا على بعض عمليات الاستبدال الناجحة لـ :+1:.

هذا يبدو غريبًا بعض الشيء. هل حاولت إعادة التعيين مرة أخرى؟
يمكنك أيضًا إرجاع عدد المشاركات التي لا تزال تحتوي على :THUMBS-UP: بسهولة باستخدام مستكشف البيانات إذا كانت هذه المعلومات مفيدة.

نعم، إنه غريب. لقد حاولت تشغيل نفس الأمر مرتين ثلاث مرات أخرى، وفي كل مرة أعاد تعيين 333 منشورًا إضافيًا… :question:

في السجل، يظهر لي الكثير من الاستبدالات المفترضة، باستثناء أنه عندما أقوم بإعادة تحميل الصفحة وأفحص المنشور الفعلي، فإنه يظل دون تغيير:

بدا هذا وكأنه مشكلة في التخزين المؤقت، لذلك قمت بتشغيل redis-cli flushall وقمت بإعادة تحميل Discourse بقوة، ولكن لا يزال لا يوجد تغيير في المنشورات التي تم الإبلاغ عن تعديلها في السجل.

وأيضًا في سجل الأخطاء، تظهر الكثير من الرسائل مثل هذه:
Screenshot from 2023-01-06 12-47-36

هذا يجب أن يكون جيدًا… ولكن إحدى المشاكل هي أنه يبدو أنه يمكنك اقتباس أشياء أخرى مثل الفواصل، ولكن لا يمكنك ذلك لأن علامات الاقتباس يتم استهلاكها بواسطة الصدفة (shell)، وليس بواسطة محلل rake.

على سبيل المثال:

→ rake posts:remap["a,b","a+b"]
ERROR: Expecting rake posts:remap['find','replace',type] where type is string or regex

ويجب اقتباس الأقواس لأنها رموز خاصة بالصدفة (shell metachars) بحد ذاتها. لن تتمكن حتى من تشغيل الأمر بملف يسمى posts:remapa في الدليل (على الرغم من أن هذا غير مرجح) أو مع تعيين failglob.

أعتقد أنه يجب علينا تغيير هذه الأوامر - فهي مضللة بمعنى أنها تبدو وكأنك تقتبس السلاسل التي يتم استبدالها، ولكننا في الواقع لا نفعل ذلك. يتم استهلاك علامات الاقتباس بواسطة الصدفة؛ ولن يراها Rails أبدًا. لا يوجد سبب لوجود علامات الاقتباس، وإذا رآها Rails فستكون جزءًا من السلسلة:

→ rake 'posts:remap["find","replace"]'
Are you sure you want to replace all string occurrences of '"find"' with '"replace"'? (Y/n)

بعض الأمثلة الإضافية بما في ذلك كيفية التعامل مع أشياء مثل الفواصل هي:

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]'

على الرغم من ذلك، وبشكل غريب، يعمل هذا:

→ rake 'posts:remap[string with a bracket] either quoted\] or not,string without a bracket]'
Are you sure you want to replace all string occurrences of 'string with a bracket] either quoted] or not' with 'string without a bracket'? (Y/n)
إعجاب واحد (1)

هل من الممكن أن يكون النص الخام قد تغير، ولكن لم يتم “خبز” المنشور (الجديد) بعد؟

فكرت في ذلك أيضًا، ولكن لا، لقد ضغطت على زر التعديل في تلك المشاركات ولم يتغير النص الأصلي. وفي عمليات الاستبدال الناجحة، يظهر الرمز التعبيري الجديد بدون إعادة خبز.

إعجاب واحد (1)

إذًا، أحاول استبدال أكثر من 600 رابط يوتيوب مستورد، لكن يبدو أنه يعمل فقط عندما يكون في سطر بمفرده.

لذا أحتاج إلى إدراج سطر جديد قبل رابط يوتيوب نفسه. لحسن الحظ، لدي سلسلة نصية من نوع “replaceme” يمكن استبدالها بسطر جديد.

هل الطريقة المناسبة هي سطر جديد في Ruby؟ أو سطر جديد في Markdown؟

هل سينجح شيء كهذا؟

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

أم أحتاج إلى تهريب الـ \n عدة مرات؟

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

أم يجب أن أستهدف سطر Markdown الجديد (وهو شرطة مائلة واحدة، صحيح؟):

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

أعتقد أنني سأحتاج إلى تهريب ذلك أيضًا؟

أي توجيهات ستكون محل تقدير.

سأفعل ذلك في ريلز حيث لا داعي للقلق بشأن العديد من مستويات الاقتباس.

إعجابَين (2)

فكرة جيدة. الهروب من الأشياء يجعل رأسي يؤلمني.

أرى أن الكود الخاص بك أعلاه سهل بما فيه الكفاية. شيء كهذا؟

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

شيء كهذا؟ أفترض أن علامة الخط المائل / في ماركداون أفضل من استخدام CR/LF أو \n، أو حتى
أو أي شيء آخر؟

كيف يمكن تشغيل هذا من سطر الأوامر؟ فقط اكتب “rails” ثم انسخ الكود هناك؟