VI除了模式外删除所有内容

4

我有一个庞大的JSON输出,我只需要删除每行中除一个小字符串以外的所有内容。

该字符串格式如下:

"title": "someServerName"

“someServerName”(引号内的部分)可能会大不相同。 我目前所能找到的最接近的翻译是:
:%s/\("title":\s"*"\)

但这只能成功删除


"title": "

每行中我想要保留的只有:

"title": "someServerName"

编辑回答发布的问题:

我将要处理的文本格式类似于

{"_links": {"self": {"href": "/api/v2/servers/32", "title": "someServerName"},tons_of_other_json_crap_goes_here

在最后我想要的只有:
"title": "someServerName"

1
你能否发布一下你的输入和期望的输出是什么?在你的帖子中并不是很清楚。 - edi9999
5个回答

13

为匹配任意字符组,请使用.*而不是*。以下方法可以实现:

%s/^.*\("title":\s".*"\).*$/\1/

每个部分的说明:

  • %s/ 在每个匹配行上进行替换。
  • ^.* 忽略从行开头开始的任何字符。
  • \("title":\s".*"\) 捕获标题和服务器名称。 ".*"将匹配引号之间的任何字符。
  • .*$ 忽略行的其余部分。
  • /\1/ 替换的结果将是第一个捕获的组。该组由括号\(...\)捕获。

请您能否提供每个部分的详细说明?我知道其中很多,但通常人们会用不同的方式解释。我还想看看是否可以尝试更改此内容,以便在文件中保留每个“title”:“someServerName”的实例,如果有多个该模式的实例。 - Carl_Friedrich_Gauss
好的,我添加了一个细分。该命令确实处理多个匹配行。 - Jim K

5
这听起来像是使用 grep 的工作。
:%!grep -o '"title":\s*"[^"]*"'

如果需要更多关于Vim过滤的帮助,请查看:h :range!

有关-o/--only-matching标志的更多信息,请参阅man grep


1
如果你将替换命令分成以下两个步骤,那么它就非常方便了。 (p.s. 我最近从好的指南书《Practical Vim》中学到了这个技巧)。
第一步:搜索您想要保留的内容
- `\v"title":\s.*"` 这将匹配 "title": "someServerName"。您可以尝试多次使用命令 `q/` 打开搜索命令窗口并修改正则表达式 (我认为这是最优秀的部分)。 - `\v^.*("title":\s.*").*$` 然后添加括号以供后续使用,并添加 .* 来匹配其他您希望删除的部分。
第二步:替换匹配的内容
- `:%s//\1/g` 注意,在此替换命令中,原始字符串是上次搜索中匹配的部分 (vim 中非常好的功能)。并且 `\1` 表示使用匹配组,实际上是您希望保留的部分。
希望您会发现它比冗长的模糊替换命令更方便。

-1
 %s/\v.*("title":\s".*").*/\1

解释和源代码在这里


-1

我认为解决这个问题最优雅的方式是使用':g'。 更详细的细节请参见下面的链接! G 的能力

它可能无法完全实现您要查找的内容,但非常接近 ;)


2
请记住,这是一篇非常古老的帖子。尝试发布一个具体的答案,例如使用:g!/pattern/d。 - Sameer Naik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接