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 "========"
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 ofjoin
, 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
Example eighteen
Purpose : Add a separator below all lines starting with "module"
:g/^module/t.|s/./\//g
Example nineteen
Purpose : Print the second line under a line of characters to an existing file
:g/^Chapter/+2w >> context
Quote:
https://vim.fandom.com/wiki/Power_of_g
https://wsdjeg.spacevim.org/vim-global-substitute/
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。