vim global

:global command is (one of) the most powerful commands in Vim. It allows you to find a match and execute a command there. Its general form is:

 :[range]g/{pattern}/{command}

Execute the command command on each matching line. This command can only be a colon command, normal mode commands cannot be used here. If needed, you can use the :normal command.

If you want to see the commands you can use, you can help ex-cmd-index . For a detailed explanation, see help 10.4 and help multi-repeat .

vglobal equivalent to global! , the two can be used in combination, such as :g/found/v/notfound/{cmd}

Using global we can string together a lot of what we've learned before to make some really fantastic moves.

So let's learn the usage of global through examples.

Example

Example 1

Usage : Display the matching line up and down a total of 3 lines, the second writing method can see the upper and lower lines more clearly

 :g/patttern/z#.3
:g/pattern/z#.3|echo "========"

图片.png

Regarding the usage of z, you can enter help :z , as shown below

:{range}z[+-^.=]{count}

Displays several lines of text surrounding the line specified by {range}. If there is no {range}, display the text above and below the current line. If there is {count}, it specifies the number of lines you can see. Otherwise, if there is only one window, use twice the value of the 'scroll' option. Otherwise, use the current window size minus 3.

If {count} is provided, the 'window' option will be set to that value.

:z can be used alone or followed by one of several punctuation marks. They have the following effects:

mark first line last line new cursor line
+ current line 1 screen forward 1 screen forward
- 1 screen backward current line current line
^ 2 screens back 1 screen backward 1 screen backward
. 1/2 screen backward 1/2 screen forward 1/2 screen forward
= 1/2 screen backward 1/2 screen forward current line

Specifying no flag is equivalent to specifying "+". If the token is "=", the current line will be surrounded by two lines consisting of hyphens.

:{range}z#[+-^.=]{count}
Like ":z", but display line numbers.

Example 2

Usage : delete all matching lines or all non-matching lines

 :g/pattern/d
:g!/pattern/d
:v/pattern/d

g! and v are equivalent.

One use of this example is to delete all blank lines

 :g/^\s*$/d

Example three

Usage : add a blank line between all lines

 :g/^/pu =\"\n\"

For the usage of pu , you can enter :help :put

:[line]pu[t] [x]
Place text [from register x] after line number [line] (defaults to the current line). It is always |linewise| line action, so this command can be used to place the extracted block on a new line. A register can also be '=', followed by an optional expression. The expression continues until the end of the command. You need to prefix the '|' and '"' characters with a backslash so that they do not terminate your command line. For example: :put ='path' . \",/test\" ; if there is no expression after the '=' expression, Vim uses the previous expression. You can see it with ":dis=".|

Example four

Usage : Append all matching lines to the end of the file

 :g/pattern/t$

For the usage of t , you can enter help :t . Its usage is the same as copy

command usage
:[line]pu[t]![x] Place text [from register x] before line number [line] (defaults to the current line).
:[range]co[py] {address} Copies the line specified by [range] below the line specified by {address}.
:[range]m[ove] {address} Moves the line specified by [range] below the line specified by {address}.

Example five

Usage : move all matching lines to the end of the file

 :g/pattern/m$

Similar to Example 4

Example six

Usage : copy all matching lines to register 'a'

 qaq:g/pattern/y A

The command here is divided into two parts:

qaq : Clear the contents of register 'a'
:g/pattern/y A : y A is an Ex command, you can use help :yank to understand the specific effect, it copies (appends) all matching lines to register 'a' .

:[range]y[ank] [x]
Extract the line specified by [range] [to register x]. Extraction to "* or "+ registers is only possible if the |+clipboard| feature is included.

:[range]y[ank] [x] {count}
Extract {count} lines [to register x] starting from the last line of [range] (default: current line |cmdline-ranges|).

Example seven

Usage : Add 1 to the number at the beginning of the line from the current line to the end of the line

 :.,$g/^\d\+/exe "normal! \<C-A>"

.,$ : From this line to the end of the line
^\d\+ : number at the beginning of the line
exe "normal! \<C-A> : Execute the normal command, which is equivalent to pressing <CA> on the matching item, <CA> can add 1 to the current number

For special characters, you can enter help expr-quote to view
"string" string constant expr-quote

Note the use of double quotes.

String constants accept the following special characters:

character meaning
\... Three-digit octal number (for example, "\316")
\.. Two octal digits (must be followed by a non-digit)
\. One octal digit (must be followed by a non-digit)
\x.. Byte specified by two hexadecimal digits (for example, "\x1f")
\x. A byte specified by a hexadecimal digit (must be followed by a non-hexadecimal digit)
\X.. Equivalent to \x..
\X. Equivalent to \x.
\u.... Four-digit hexadecimal specified character. Store in the encoding determined by the current value of 'encoding' (eg "\u02a4")
\U.... Equivalent to \u but accepts up to 8 hexadecimal digits.
\b Backspace <BS>
\e escape <Esc>
\f form feed <FF>
\n newline <NL>
\r Enter <CR>
\t Tab <Tab>
\\ backslash
\" Double quotes
\<xxx> Special characters named "xxx", eg "\<CW>" for CTRL-W. For mapping, 0x80 bytes are escaped.

Double quotes must be escaped: "<M-\">" .
Don't use <Char-xxxx> to get utf-8 characters, use \uxxxxx as mentioned above.
Note that "\xff" is stored as byte 255, which is not legal in some encodings. Use "\u00ff" to save character 255 with the current value of 'encoding'.
Note that "\000" and "\x00" force end of string.

About increment and decrement, you can use help CTRL-A to view

Increment and decrement~
CTRL-A
Add [count] to the number or letter above or after the current cursor.

{Visual}CTRL-A
Add [count] to the value or letter in the highlighted text.

{Visual}g CTRL-A
Add [count] to the value or letter in the highlighted text. If more than one line is highlighted, an additional [count] will be added to each line (ie, an incrementing sequence of increments of [count] is generated).

For example, suppose you have a list of numbers like this:

 1. 
1. 
1. 
1.

Move to the second "1.", visually select the last three lines, and press g CTRL-A to generate:

 1. 
2. 
3. 
4.

CTRL-X
Subtract [count] from the number or letter above or after the current cursor.

{Visual}CTRL-X
Subtract [count] from the number or letter in the highlighted text.

On MS-Windows, this key is mapped to cut visual text |dos-standard-mappings|. To block this mapping, use: silent! vunmap <C-X>

{Visual}g CTRL-X
Subtract [count] from the number or letter in the highlighted text. If more than one line is highlighted, an additional [count] is subtracted from each line (ie, a descending sequence with [count] increments) is generated.

The CTRL-A and CTRL-X commands can be used to:

  • Signed or unsigned decimal number
  • Unsigned binary, octal and hexadecimal numbers
  • letter

Example eight

Purpose : Use /.../ to become a comment on all lines containing DEBUG

 " using :normal
g/^\s*DEBUG/exe "norm! I/* \<Esc>A */\<Esc>"
" using :substituting
g/^\s*DEBUG/s!.*!/* & */!

Here & is used to denote the entire preceding match

Example nine

Purpose : Display the previous line of the matching line

 :g/pattern/?^\w?p                   "if only name is interesting
:g/pattern/ka|?^\w?p|'ap            "if name and the lookup-line is interesting
:g/pattern/?^\w?|+,/^[^ ]/+1p       "if entire record is interesting

About ?^\w?, 两个 ? 之间的就是要匹配的模式, ^\w 表示开头不为空的行, p 表示 has already said before
? can view help cmdline-range .

symbol line number
{number} line number
. current line
$ last line of file
% Equivalent to 1,$ (whole file)
't position of marker t (lowercase)
'T The position of the marker T (uppercase); if the marker exists in another file, it cannot be applied in scope.
/{pattern}[/] next line matching {pattern}
?{pattern}[?] previous line matching {pattern}
/ the next line that matches the previous search pattern
? the previous line that matched the previous search pattern
\& the next line that matches the previous replacement pattern

About ka , you can view help :k

:[range]ma[rk] {a-zA-Z'}
Set the position marker {a-zA-Z'} in the last row, column 0 of [range]. The default [range] is the current line.

:[range]k{a-zA-Z'}
Same as :mark, but the space before the tagname can be omitted.

Example ten

Purpose : Reverse file lines

 :g/^/m0

As mentioned earlier m means move

Example eleven

Purpose : Add a character to the end of a line switched with a keyword

 :g/^pattern/s/$/mytext/

Example twelve

Purpose : delete matching lines

 :g/pattern/d _

By default, all deleted lines will be copied to the unnamed register. When there are many files, the performance will be affected, so copy the content to the black hole register here, which is equivalent to NOP , which can improve performance

Some common commands:

 :2,8co15  "copy lines 2 through 8 after line 15
:4,15t$   "copy lines 4 through 15 to end of document (t == co)
:-t$      "copy previous line to end of document
:m0       "move current line to line 0 (i.e. the top of the document)
:.,+3m$-1 "current line through current+3 are moved to the lastLine-1 (i.e. next to last)

Example Thirteen

Purpose : replace characters in a range

 :'a,'bg/pattern/s/pattern2/string/gi

Example fourteen

Purpose : In the matching line, execute the action in register q

 :g/pattern/normal @q

Example fifteen

Purpose : Delete consecutive duplicate lines

 :g/^\(.*\)\(\r\?\n\1\)\+$/d
:%!uniq

\r\?\n can be used to match newlines, \r is optional when g is used to search for multi-line matches, it only applies the command to the first match line, not the entire match

Example sixteen

Purpose : Merge empty rows of multiple connections to one line

 :v/./,/./-j
  • j is a synthesis of join , which concatenates multiple lines into one line.
  • ,/./- is a range, the full form is .,/./-1 , which means the current line to the previous line of a non-blank line

J
Concatenate [count] lines, but at least two lines. Remove indentation and insert no more than two spaces (see below). Doing this at the end of the buffer will fail. [count] If it is too much, it will shrink itself to the remaining available lines.

{Visual}J
Concatenate highlighted lines, but contain at least two lines. Remove indentation and insert no more than two spaces (see below).

gJ
Concatenate [count] lines, but at least two lines. No spaces are inserted or deleted.

{Visual}gJ
Concatenate highlighted lines, but contain at least two lines. No spaces are inserted or deleted.

[range]j[oin][!] [flags]
Concatenates the rows of the [range] range. Same as "J", but join does not insert or delete any spaces when [!] is present. If [range] includes the same start and end line, this command does nothing. The default behavior is to concatenate the current line with the next line. See |ex-flags| for the [flags] section.

:[range]j[oin][!] {count} [flags]
Concatenate {count} lines starting with [range] (default: current line |cmdline-ranges|). Same as "J", but join does not insert or delete any spaces when [!] is present. See |ex-flags| for the [flags] section.

Example seventeen

Purpose : Alphabetically sorts port declarations surrounded by keywords

 :g/\/\/define begin/+1,/\/\/define end/-1 sort:g/{/ .+1,/}/-1 sort

图片.png

Example eighteen

Purpose : Add a separator below all lines starting with "module"

 :g/^module/t.|s/./\//g

图片.png

Example nineteen

Purpose : Print the second line under a line of characters to an existing file

 :g/^Chapter/+2w >> context

图片.png

Quote:
https://vim.fandom.com/wiki/Power_of_g
https://wsdjeg.spacevim.org/vim-global-substitute/


harriszh
338 声望131 粉丝

做些有趣的事,留些有用的存在