4

考虑这两个 vim 命令

  1. :% s/one/two/g
  2. :% g/found/d

我想知道为什么g信号全局替换和删除需要分别放在最后替换和删除开头。

这些是否遵循我缺少的模式,或者这是 vim 极端情况?

4

3 回答 3

8

我猜你对:g[lobal],:s[ubstitute]:[range]delete

让我们举个例子:

g是一个标志:s

  • :s/foo/bar/ : 只替换当前中的第一个 foobar
  • :s/foo/bar/g :全部 foo替换bar当前
  • %:s/foo/bar/ :对于整个文件中的每一行,仅将第一 foo行替换为bar
  • %:s/foo/bar/g:用整个文件 替换所有 (所有行)foobar

:gas :globalcommand ::g可以处理任何命令,不仅d

  • :g/foo/d: 删除所有匹配的行 默认范围是%
  • :%g/foo/d: 同上
  • :1,30g/foo/d:从第 1-30 行,删除所有包含foo
  • :g/foo/normal >>: 缩进所有匹配的行foo(不仅适用于d
  • :g/foo/y A: 拉出所有匹配的 ( /foo/) 行以进行注册a(不仅适用于d

:d命令:( :[range]d[elete])

  • :/foo/d:/foo/这是一个范围。删除下一个匹配行
  • :%d:删除所有行(清空文件)
  • :%/foo/d: 这个不行。因为你有两个范围(% 和 /foo/)
  • :/foo/dg: 这也行不通。没有dg命令
  • :g/foo/d:这有效,与上面(该:g部分)相同,但它来自:global命令

我希望你能清楚一点。(或者更困惑?我希望不会.. ^_^)

你可能想看看以下

:h :s
:h :g
:h :d
:h range
于 2013-03-11T00:05:48.753 回答
3

稍微不同地解释一下:

:% g/found/d

这里g:g[lobal]的缩写形式,格式如下:

:[range]g/pattern/[command]

它的工作原理是:

  1. 扫描其中的每一行[range](如果未[range]指定,则扫描所有行),
  2. 标记所有匹配pattern,并且
  3. 执行给定的[command].

注意:pattern[range]执行. _ [command]仅对标记匹配的命令执行pattern

:% s/one/two/g

这里,g[flags]from :s[ubstitution]命令之一,其格式如下:

:[range]s[ubstitute]/pattern/string/[flags]

它的工作原理是:

  1. 扫描其中的每一行[range](如果没有[range]指定,则只扫描当前行),
  2. 标记所有匹配pattern
  3. pattern,string
  4. 调用[flags](例如,“c”表示确认,“g”表示所有出现)。

注意:与 command 不同,g这里是一个本地化标志:s[ubstitution],不与其他命令一起普遍:g[lobal]使用。

一起使用:g[lobal]_:s[ubstitute]

将命令替换[command]为,我们得到以下格式::g[lobal]:s[ubstitution]

:[range_g]g/pattern_g/[range_s]s/pattern_s/string_s/[flags]

通过分析,我们了解到以下几点:

  1. 我们的世界仅限于pattern_g内部的匹配[range_g]
  2. 在这个有限的世界里,我们正在执行命令:s[ubstitute]
  3. :s[ubstitute]仅当匹配pattern_s发生在中时才会执行此操作[range_s]

例子:

给定以下文本:

stackoverflow.com/
stackexchange.com/
stackoverflow.com 
stackexchange.com
www.stackoverflow.com
www.stackexchange.com
http://www.stackoverflow.com
http://www.stackexchange.com // your cursor is placed here

情况1::g/com/d

// all lines are deleted

案例二::g/com$/d

stackoverflow.com/
stackoverflow.com/
// all lines containting com at the end are deleted

案例 3::g/com$/s/exchange/overflow/g

stackoverflow.com/
stackexchange.com/
stackoverflow.com 
stackoverflow.com // changed
www.stackoverflow.com
www.stackoverflow.com // changed
http://www.stackoverflow.com
http://www.stackoverflow.com // changed

案例 4::1,7g/com$/s/exchange/overflow/g

stackoverflow.com/
stackexchange.com/
stackoverflow.com 
stackoverflow.com // changed
www.stackoverflow.com
www.stackoverflow.com // changed
http://www.stackoverflow.com
http://www.stackoverflow.com

案例 5::1,7g/com$/4,6s/exchange/overflow/

stackoverflow.com/
stackexchange.com/
stackoverflow.com 
stackoverflow.com // changed
www.stackoverflow.com
www.stackexchange.com
http://www.stackoverflow.com
http://www.stackoverflow.com

案例 6::1,7g/com$/4,6s/exchange/overflow/g

stackoverflow.com/
stackexchange.com/
stackoverflow.com 
stackoverflow.com // changed
www.stackoverflow.com
www.stackexchange.com // changed 
http://www.stackoverflow.com
http://www.stackexchange.com

案例 7::s/exchange/overflow/g

stackoverflow.com/
stackexchange.com/
stackoverflow.com 
stackexchange.com
www.stackoverflow.com
www.stackexchange.com
http://www.stackoverflow.com
http://www.stackoverflow.com // changed. only current line is executed 
于 2013-03-11T02:51:43.823 回答
1

s//g是全局替换就行了。 g/是文档上的全局替换。在第一种情况下,%s对整个文档进行替换。如果没有g结尾,它仍然会在整个文档上进行替换,但只会在每行的第一个实例上进行。 %/是无效的语法,但://d将替换找到的下一行,类似于如何:s//替换当前行。请注意,您不需要%g. 只是g在你的例子中会做同样的事情。

于 2013-03-10T23:41:19.860 回答