考虑这两个 vim 命令
:% s/one/two/g
:% g/found/d
我想知道为什么g
信号全局替换和删除需要分别放在最后替换和删除开头。
这些是否遵循我缺少的模式,或者这是 vim 极端情况?
我猜你对:g[lobal]
,:s[ubstitute]
和:[range]delete
让我们举个例子:
g
是一个标志::s
:s/foo/bar/
: 只替换当前行中的第一个 foo
bar
:s/foo/bar/g
:全部 foo
替换bar
为当前行%:s/foo/bar/
:对于整个文件中的每一行,仅将第一 foo
行替换为bar
%:s/foo/bar/g
:用整个文件 替换所有 (所有行)foo
bar
:g
as :global
command ::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
稍微不同地解释一下:
:% g/found/d
这里g
是:g[lobal]的缩写形式,格式如下:
:[range]g/pattern/[command]
它的工作原理是:
[range]
(如果未[range]
指定,则扫描所有行),pattern
,并且[command]
.注意:pattern
在[range]
执行. _ [command]
仅对标记匹配的命令执行pattern
。
:% s/one/two/g
这里,g
是[flags]
from :s[ubstitution]命令之一,其格式如下:
:[range]s[ubstitute]/pattern/string/[flags]
它的工作原理是:
[range]
(如果没有[range]
指定,则只扫描当前行),pattern
,pattern
,string
和[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]
通过分析,我们了解到以下几点:
pattern_g
内部的匹配[range_g]
。:s[ubstitute]
。: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
s//g
是全局替换就行了。 g/
是文档上的全局替换。在第一种情况下,%s
对整个文档进行替换。如果没有g
结尾,它仍然会在整个文档上进行替换,但只会在每行的第一个实例上进行。 %/
是无效的语法,但://d
将替换找到的下一行,类似于如何:s//
替换当前行。请注意,您不需要%g
. 只是g
在你的例子中会做同样的事情。