Consistency in global operations in vim

Consider these two vim commands

  • :% s/one/two/g
  • :% g/found/d

I am wondering why the global replacement and removal of signaling g , respectively, should be set at the end of the substitution and at the beginning in delete.

Do they follow the pattern that I am missing, or is it a case from a vim angle?

+4
source share
3 answers

I think you are confused with :g[lobal] :s[ubstitute] and :[range]delete

let's make an example:

g - flag :s :

  • :s/foo/bar/ : replace only the first foo with bar in the current line
  • :s/foo/bar/g : replace all foo with bar in the current line
  • %:s/foo/bar/ : for each line in the entire file, replace << → << → bar only
first foo %:s/foo/bar/g : replace all foo with bar in the whole file (all lines)

:g like :global command :: :g can execute any command, not just d

  • :g/foo/d : remove all default match for default range %
  • :%g/foo/d : same as above
  • :1,30g/foo/d : from line 1-30 remove all lines containing foo
  • :g/foo/normal >> : indent all lines that match foo (not just working with d )
  • :g/foo/y A : print all matched lines ( /foo/ ) for registering a (not only working with d )

:d command: ( :[range]d[elete] )

  • :/foo/d : /foo/ Here is the range. delete next matching line
  • :%d : delete all lines (empty file)
  • :%/foo/d : this will not work. because you have two ranges (% and / foo /)
  • :/foo/dg : this will not work either. no dg team
  • :g/foo/d : this works the same as above (section :g ), but from the command :global

I hope you will be clear. (or more confused? I hope not .. ^ _ ^)

You can see below.

 :h :s :h :g :h :d :h range 
+8
source

Explain a little differently:

:% g/found/d

Here g is an abbreviated form : g [lobal] , which has the following format:

 :[range]g/pattern/[command] 

And it works:

  • scanning each line inside [range] (if [range] is not specified, all lines are scanned),
  • marking all matches pattern and
  • execution of the given [command] .

NOTE. All occurrences of pattern matching within [range] are marked before executing [command] . Commands are executed only for marked pattern matching.

:% s/one/two/g

Here g is one of the [flags] of : s [ubstitution] of the command, which has the following format:

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

And it works:

  • scanning each line inside [range] (if [range] is not specified, only the current line is checked),
  • marking all matches pattern ,
  • substituting pattern the above two conditions with string and
  • calling [flags] (for example, "c" to confirm, "g" for all occurrences).

NOTE. g is the localized flag for :s[ubstitution] and is not universally used with other commands, unlike the command :g[lobal] .

Using :g[lobal] and :s[ubstitute] together

Replacing the command [command] from :g[lobal] with :s[ubstitution] , we get the following format:

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

By analyzing, we find out the following:

  • Our world is limited to matching pattern_g inside [range_g] .
  • In this limited world, we execute the command :s[ubstitute] .
  • This :s[ubstitute] is executed only if pattern_s matches inside [range_s] .

Example:

Given the following text:

 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 

CASE 1:: :g/com/d

 // all lines are deleted 

CASE 2:: :g/com$/d

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

CASE 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 

CASE 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 

CASE 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 

CASE 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 

CASE 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 
+3
source

s//g is a global line replacement. g/ is a global replacement for the document. In the first case, %s replaces the entire document. Without g at the end, it will still replace the entire document, but only in the first instance of each line. %/ is not valid syntax, but ://d will replace the next line, found in the same way as :s// will be replaced on the current line. Note that you do not need %g . Just g in your example will do the same.

+1
source

All Articles