考虑这两个 vim 命令
:% s/one/two/g:% g/found/d
我想知道为什么g信号全局替换和删除需要分别放在最后替换和删除开头。
这些是否遵循我缺少的模式,或者这是 vim 极端情况?
我猜你对: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
稍微不同地解释一下:
:% 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在你的例子中会做同样的事情。