# 在所有帖子中替换字符串

**URL:** https://meta.discourse.org/t/replace-a-string-in-all-posts/48729
**Category:** Self-Hosting
**Tags:** how-to
**Created:** [2016年八月17日 10:23 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729 "2016-08-17T10:23:49Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Discourse](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/discourse/32/148734_2.png) [@Discourse](https://meta.discourse.org/u/Discourse)
#### Post date: [2016年八月17日 10:23 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/1 "2016-08-17T10:23:49Z")

</div>

> 🔖 This guide explains how to replace a string in all posts within a Discourse instance.
> 
> 🙋 Required user level: System Administrator
> 
> ⚠ Console Access Required

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

> ⚠ **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:

```bash
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:

```bash
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:

```bash
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:

```bash
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:

```bash
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

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

```

### Case-insensitive deletion

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

```

### Regex deletion

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

```

> Last edited by @SaraDev 2024-11-14T00:39:05Z
> 
> > **Check document**
> >
> > Perform check on document:

---

<div class="post-metadata">

### Author: ![nathank](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nathank/32/290039_2.png) [@nathank](https://meta.discourse.org/u/nathank)
#### Post date: [2022年五月12日 06:17 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/147 "2022-05-12T06:17:35Z")

</div>

如何只针对单个类别中的主题执行此操作？

我的用例是导入的 RSS 提要，它烦人地显示 `?` 而不是 `'`。由于该提要是新闻提要，其中包含大量引语，因此这是一个问题！

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2022年五月12日 17:19 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/148 "2022-05-12T17:19:10Z")

</div>

> [@nathankershaw](#):
>
> 如何只针对单个分类中的主题执行此操作？

您需要从 Rails 进行操作，这会比较困难，因为帖子不属于分类，而主题属于。如果这是一个持续存在的问题，听起来您需要一个插件。您可以巧妙地使用联接，或者像这样循环：

```plaintext
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:` 中，则不包含该部分。

如果帖子数量不是很大，那么这可能就足够了，如果它能正常工作的话。

---

<div class="post-metadata">

### Author: ![nathank](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nathank/32/290039_2.png) [@nathank](https://meta.discourse.org/u/nathank)
#### Post date: [2022年五月12日 22:02 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/149 "2022-05-12T22:02:07Z")

</div>

谢谢 Jay！这会很好地解决问题。

> [@pfaffman](#):
>
> 听起来如果这是一个持续存在的问题，您需要一个插件。

我确实需要正确地对其进行故障排除，看看是否有上游修复。或者我可能需要对 [RSS Polling Plugin](https://meta.discourse.org/t/configure-the-discourse-rss-polling-plugin/156387) 进行一些补充，这有点棘手！

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [2022年五月12日 22:09 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/150 "2022-05-12T22:09:50Z")

</div>

> [@nathankershaw](#):
>
> 我的用例是一个导入的 RSS 源，它烦人地显示一个 `?` 而不是一个 `'`。

只是猜测一下，您是否还遇到来自 RSS 源的帖子的其他问题？在查看源的提要时，是否会出现 `?` 字符？我想知道您遇到的问题是否是编码问题。

---

<div class="post-metadata">

### Author: ![nathank](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nathank/32/290039_2.png) [@nathank](https://meta.discourse.org/u/nathank)
#### Post date: [2022年五月12日 22:15 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/151 "2022-05-12T22:15:17Z")

</div>

> [@simon](#):
>
> 在查看 feed 的源代码时，是否能看到 `?` 字符？

是的，我现在就看这个。每次出现不寻常的字符时，里面都有 `?`，所以这是 RSS 源端的问题。事实证明，`'` 只是最常见的字符，但 `ā`、`\"` 和其他一两个字符也出现了这种情况。

不幸的是，所涉及的软件公司不像 Discourse 团队那样响应迅速 😘！祝我好运。

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2022年五月12日 22:52 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/152 "2022-05-12T22:52:16Z")

</div>

> [@simon](#):
>
> 我怀疑你遇到的可能是编码问题。

我也是这么想的。也许只需更好地检测正确的编码即可。

---

<div class="post-metadata">

### Author: ![Chandra](https://avatars.discourse-cdn.com/v4/letter/c/57b2e6/32.png) [@Chandra](https://meta.discourse.org/u/Chandra)
#### Post date: [2022年十月14日 19:50 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/153 "2022-10-14T19:50:47Z")

</div>

请问如何将其替换为如下内容？

[member=12345] → @

---

<div class="post-metadata">

### Author: ![Brandon007](https://avatars.discourse-cdn.com/v4/letter/b/b4bc9f/32.png) [@Brandon007](https://meta.discourse.org/u/Brandon007)
#### Post date: [2022年十一月19日 14:57 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/154 "2022-11-19T14:57:49Z")

</div>

> [@techAPJ](#):
>
> `rake posts:remap["find","replace","string",true]`

我使用了这个示例，它可以替换 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`

我也尝试了错误消息中显示的单引号，但没有成功。我甚至尝试像删除单词示例那样在单词之间放置连字符。结果是相同的错误。

有什么建议吗？

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2022年十一月19日 15:38 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/155 "2022-11-19T15:38:59Z")

</div>

我担心如果你需要处理引号，最好在 rails 中进行。使用 rake 任务，你必须同时处理 `bash` 和 rails 来转义。你可能需要使用一堆反斜杠（也需要转义），但可能不行。

看看我上面提供的 rails 示例，看看是否有意义。下次我拿到笔记本电脑时，我会往 OP 中添加一些内容。

---

<div class="post-metadata">

### Author: ![Brandon007](https://avatars.discourse-cdn.com/v4/letter/b/b4bc9f/32.png) [@Brandon007](https://meta.discourse.org/u/Brandon007)
#### Post date: [2022年十一月19日 16:21 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/156 "2022-11-19T16:21:57Z")

</div>

感谢您的回复。这超出了我的能力范围，但我可以学习。

听起来文本字符串中的引号是导致我问题的原因……

我的目的是更改博客的标题和网址，因此我喜欢回到论坛更新这些链接、标题和网址。我认为在进行 SEO 工作时，这项任务会变得相当频繁。如果能提供更多细节，那就太好了。

---

<div class="post-metadata">

### Author: ![rahim123](https://avatars.discourse-cdn.com/v4/letter/r/df705f/32.png) [@rahim123](https://meta.discourse.org/u/rahim123)
#### Post date: [2023年一月6日 13:57 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/157 "2023-01-06T13:57:16Z")

</div>

我一定有什么地方没弄明白。我正试图将近 300 万条帖子（包括私信）中的 `:THUMBS-UP:` 替换为 `:+1:`。我运行了：  
`rake posts:remap[\":THUMBS-UP:\",\":+1:\"]`  
大约 50 分钟后，它返回了 `40000 posts remapped!` 这个数字看起来可疑地规整。我确实发现了一些在最近的帖子和很多年前的帖子中被替换成了 `:+1:` 的情况，但在那些也有成功替换成 `:+1:` 的帖子中，仍然有大量的 `:THUMBS-UP:` 存在。

---

<div class="post-metadata">

### Author: ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)
#### Post date: [2023年一月6日 16:07 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/158 "2023-01-06T16:07:24Z")

</div>

这似乎有点奇怪。你再试着重新映射了吗？  
如果你想用数据资源管理器（data-explorer）来统计仍然包含 `:THUMBS-UP:` 的帖子数量，也可以轻松做到，如果这些信息对你有用的话。

---

<div class="post-metadata">

### Author: ![rahim123](https://avatars.discourse-cdn.com/v4/letter/r/df705f/32.png) [@rahim123](https://meta.discourse.org/u/rahim123)
#### Post date: [2023年一月6日 17:33 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/159 "2023-01-06T17:33:59Z")

</div>

是的，这很奇怪。我尝试了另外三次运行相同的命令 ~~two~~ three，每次都重新映射了另外 333 个帖子…… ❓

日志显示了一堆所谓的替换，但当我重新加载页面并检查实际帖子时，它仍然没有改变：

 ![Screenshot from 2023-01-06 12-42-28](https://global.discourse-cdn.com/meta/original/4X/f/9/e/f9eab972fb8a51a378f2ae1684cba077e3c359df.png)

这看起来像是一个缓存问题，所以我运行了 `redis-cli flushall` 并硬刷新了 Discourse，但日志中报告已编辑的帖子仍然没有变化。

并且错误日志中也出现了一堆类似这样的消息：  
 ![Screenshot from 2023-01-06 12-47-36](https://cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/meta/optimized/4X/6/b/b/6bbf5d8ca518769cdc160daf1830ada0f4dba01e_2_690x23.png)

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [2023年一月6日 18:06 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/160 "2023-01-06T18:06:30Z")

</div>

> [@Brandon007](#):
>
> `rake posts:remap["I Don't Want This Phrase","But I Do Want This One","string",true]`

这应该没问题……但其中一个问题是，它_看起来_你可以引用其他东西，比如逗号，但你不能，因为引号被 shell 消耗掉了，而不是被 rake 解析器消耗掉。

例如：

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

```

并且括号应该被引用，因为它们本身就是 shell 元字符。你甚至无法在目录中运行一个名为 `posts:remapa` 的命令（尽管这不太可能）或在设置了 `failglob` 的情况下运行。

> [@techAPJ](#):
>
> `rake posts:remap[":slightly_smiling:",":slight_smile:"]`

我认为我们应该更改这些命令——它们具有误导性，因为它们_看起来_你正在引用被替换的字符串，但实际上我们并没有。引号被 shell 消耗掉了；rails 从未见过它们。没有理由甚至要加引号，如果 rails 确实看到了它们，它们将成为字符串的一部分：

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

```

更多示例，包括如何处理逗号等内容是：

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

```

尽管如此，奇怪的是，这有效：

```plaintext
→ 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)

```

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [2023年一月6日 19:06 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/161 "2023-01-06T19:06:28Z")

</div>

> [@rahim123](#):
>
> 当我重新加载页面并检查实际帖子时，它保持不变

原始帖子是否已更改，但（新）帖子尚未生成？

---

<div class="post-metadata">

### Author: ![rahim123](https://avatars.discourse-cdn.com/v4/letter/r/df705f/32.png) [@rahim123](https://meta.discourse.org/u/rahim123)
#### Post date: [2023年一月6日 19:08 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/162 "2023-01-06T19:08:24Z")

</div>

我也这么想过，但没有，我点击了那些帖子的编辑按钮，原始内容没有改变。在成功的替换中，新的表情符号会显示出来，而无需重新烘焙。

---

<div class="post-metadata">

### Author: ![MiG](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mig/32/119486_2.png) [@MiG](https://meta.discourse.org/u/MiG)
#### Post date: [2023年一月17日 03:36 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/163 "2023-01-17T03:36:41Z")

</div>

我正在尝试替换 600 多个导入的 YouTube 链接的实例，但似乎只有当它单独占一行时才有效。

所以我需要在 YouTube 链接本身之前插入一个换行符。幸运的是，我有一个可以替换为换行符的“replaceme”类型的字符串。

这是 Ruby 换行符的正确方法吗？还是 Markdown 换行符？

像这样可以吗？

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

```

还是我需要多次转义 `\n`？

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

```

或者我应该使用 Markdown 换行符（那是单个反斜杠，对吗？）：

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

```

我猜我也需要转义那个？

任何指导都将不胜感激。

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2023年一月17日 16:38 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/164 "2023-01-17T16:38:27Z")

</div>

我会在 Rails 中这样做，这样您就不必担心如此多的引用级别。

---

<div class="post-metadata">

### Author: ![MiG](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mig/32/119486_2.png) [@MiG](https://meta.discourse.org/u/MiG)
#### Post date: [2023年一月17日 19:13 UTC](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729/165 "2023-01-17T19:13:33Z")

</div>

好主意。转义字符让我头疼。

我看到你上面的代码很容易理解。是不是像这样？

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

```

大概是这样吗？我猜 markdown / 比使用 CR/LF 或 \n，甚至 \u003cbr /\u003e 或其他什么更好？

如何在 shell 中运行它？直接输入“rails”然后把代码复制进去吗？

[下一頁](https://meta.discourse.org/t/replace-a-string-in-all-posts/48729.md?page=2&search=remap)
