Vim 的替換查找是其核心功能, 功能極其強大, 通過其規(guī)則匹配, 可以很快速地完成我們很多需要大量人力操作的工作, 而且可對多文件使用查找/替換功能.
本系列教程共分為以下五個部分:
編程界實現了多種正則匹配引擎, vim 的正則匹配引擎是獨有的, 其風格類似于 POSIX
, 但是我們可通過將其匹配模式設為:
\v
: (very magic) 來開啟 Perl
模式, 此模式下 (
已經被轉義, 如果要搜索 (
, 必須轉回原義: \(
(此模式實際上最接近大部分語言中的正則)\V
: (very nomagic) 來開啟開啟原義模式, 此模式下直接搜索(
即可搜索到 (
\m
: 默認模式, 不指定任何模式時使用的就是此模式. 此模式下僅部分字符有特殊含義, (
沒有被轉義, 仍然可通過 (
搜索到 (
\M
: (nomagic) 其功能類似于 \V
原義開關, 不同的是, 一些字符會自動具有特殊含義, 即符號 ^
與 $
本文只討論默認模式下(\m
模式)下的正則匹配, 其他模式下的原理類似, 讀者可自行研究
元字符是正則匹配的一個概念, 通過元字符可以快速找出目標字段.
.
: 表示匹配任意 一個 字符. 例: c..l
表示任意以 c 開頭, 中間有兩個任意字符, l 結尾的字段.
.*
: 表示匹配 任意多個 字符. 例: c.*l
表示任意以 c 開頭 l 結尾的字段(不會將一個字段進行跨行處理, 因此非常智能, 很頻繁使用)
\_.*
: 表示匹配 任意多個 字符(包括換行符!)
$
: 匹配行尾. 例: /d.*$
表示匹配到以 d 開頭到行尾中的所有內容, /123$
表示以 123 結尾的所有字段
^
: 匹配行首. 例: ^.*d
表示匹配到行首到 d 的所有內容, /^123
表示以 123 開頭的字段
\<
: 匹配單詞詞首
\>
: 匹配單詞詞尾. 例: /\<f\>
表示只匹配 f
單詞, 如果其前有任何字符它就不是單詞, 不會被匹配到.
*
: 表示其前字符可以重復 0~無數 次. 如 /be*
會匹配到 b
, be
, bee
..., 因為 e 重復零次就是沒有, 所以會返回 b, 貪婪匹配模式, greedy
\+
: 表示其前字符必須重復 1~無數 次, 如 /be\+
會匹配到 be
, bee
, beee
..., 貪婪匹配模式
\{-}
: 非貪婪匹配模式, non-greedy, 與 *
相對, .\{-}
與 .*
一樣表示匹配任意多個字符
\?
或 \=
: 代表其前字符必須重復 0 或者 1 次.
\{n,m}
: 其前字符必須重復 n 到 m 次, 貪婪匹配模式. (\{n,}
表示右邊界范圍為無限, {,m}
表示左邊界范圍為0)
\n
: 其前字符必須重復 n 次
\{-n,m}
: 其前字符必須重復 n 到 m 次, 非貪婪匹配模式. (\{-n,}
表示右邊界范圍為無限, {-,m}
表示左邊界范圍為0)
[adz]
: 匹配 a
, d
, z
中的任意 一個, 括號內也可是數字, 如 [2-5]
表示匹配 2
, 3
, 4
, 5
中的任意一個數字
\|
: 或的意思, 表示只要符合其前或其后任意一個字符即可. 例: /one\|two\|three
表示匹配 one, two, three 中的任意一個. end\(if\|while\|for\)
表示會查找到 endif, endwhile, endfor 中的任意一個.
[^a]
: 匹配除 a
以外的任意 字符
[a-c]
: 匹配 a
, b
, c
中的任意一個, 遞增的順序
\d
: 匹配十進制數字中的任意一個, 等同于 [0-9]
. 例: /\d\d:\d\d:\d\d
表示查找如 17:31:00
格式的字符
\D
: 匹配除十進制數字外的任意一個字符, 等同于 [^0-9]
\x
: 匹配十六進制數字中的任意一個, 等同于 [0-9A-Fa-f]
\X
: 匹配除十六進制數字外的任意一個字符, 等同于 [^0-9A-Fa-f]
\o
: 匹配八進制數字外的任意一個字符
\O
: 匹配除八進制數字外的任意一個字符
\h
: head of word character(a,b,c...z,A,B,C...Z,_
), 等同于 [a-zA-Z_]
\H
: non-head of word character, 等同于 [^a-zA-Z_]
\a
: alphabetical character, 等同于 [a-zA-Z]
\A
: non-alphabetical character, 等同于 [^a-zA-Z]
\l
: lowercase character
\L
: non-lowercase character
\u
: uppercase character
\U
: non-uppercase character
\w
: 匹配一個單詞(對中文來說非常雞肋, 因為只有 Vim 判定是單詞的才會進行匹配, 與normal 模式下的 w
, b
, e
匹配規(guī)則相同)
\W
: 匹配除單詞外的所有字符. 因為在 vim 中中文全部不被認為是單詞, 因此, 此匹配會選中所有中文字段.
\t
: 代表 tab , 可使用此方法將所有 tab 替換為空格
\s
: 配空白字段, 包含 tab 與空格, 在 pattern 中使用此查找空白, 在 string 中就可以直接使用空格或者 tab 來輸入以替換了
\S
: 匹配非空白字段, 等同于 [^\s]
\n
: 匹配換行符
\_s
: 匹配換行或空白(空格或 tab)
\_a
: 匹配換行或單詞(因為是單詞, vim 不會匹配中文)
\C
: 區(qū)分大小寫地查找或替換, 例: /\CText
表示只會查找Text
, 不會查找 text
或 tExt
等
\c
: 不區(qū)分大小寫地查找替換(已經在 vim 中設置了默認不區(qū)分了)
\zs
: set the beginning of the match
\ze
: set the end of the match
\<
: beginning of word, zero width match
\>
: end of word, zero width match
\%^
: beginning of file, zero width match
\%$
: end of file, zero width match
\@!
: negative look-ahead
\_@<!
: negative look-behind
如上所述, .
, *
, [
, ]
, ^
, %
, /
, ?
, ~
, $
等字符有特殊含義, 如果對這些進行匹配, 需要考慮添加 \
/pattern/[se]
/view
: 全文查找 view 關鍵字 (n 為向下方向)?view
: 全文查找 view 關鍵字 (n 為向上方向)/\cview
: 全文查找 view 關鍵字(大小寫不敏感):100,235g/foo/#
: 在區(qū)間 100 ~ 235
搜索, 在控制臺輸出結果:100,235il foo
: 同上/view/e
: 默認的查找會將光標置于單詞首部, 使用 e
保證光標位于尾部, 方便 .
命令的調用/view/s-2
: cursor set to start of match minus 3/view/+3
: find view move cursor 3 lines down/^joe.*fred.*bill/
: find joe and bill(joe at start of line)/^[A-J]
: search for lines beginning with one or more A-J
/begin\_.*end
: search over possible multiple lines/fred\_s*joe
: any whitespace including newline/fred\|joe
: search for fred or joe/.*fred\&.*joe
: search for fred and joe in any order/\<fred\>/
: search fro fred but not alfred or frederick/\<\d\d\d\d\>
: search for exactly 4 digit numbers/\D\d\d\d\d\D
: search for exactly 4 digit numbers/\<\d\{4}\>
: same thing/\([^0-9]\|^\)%.*%
: search for absence of a digit or beginning of line/^\n\{3}
: find 3 empty lines/^str.*\nstr
: find 2 successive lines starting with str/\(^str.*\n\)\{2}
: find 2 successive lines starting with str/\(fred\).*\(joe\).*\2.*\1
/^\([^,]*,\)\{8}
:vmap // y/<C-R>"<CR>
: search for visually highlighted text:vmap <silent> // y/<C-R>=escape(@", '\\/.*$^~[]')<CR><CR>
: with spec chars/<\zs[^>]*\ze>
: search for tag contents, ignoring chevrons/<\@<=[^>]*>\@=
: search for tag contents, ignoring chevrons/<\@<=\_[^>]*>\@=
: search for tags across possible multiple lines/\%(defg\)\@<!abc
: anything starting with abc
that's not (immediately) preceeded by defg
/\%(defg.*\)\@<!abc
: match abc
as long as it's not part of defg.*abc
/\%(defg.*\)\@<!abc \%(.*defg\)\@!
: Matching abc
only on lines where defg
doesn't occur is similar/<!--\_p\{-}-->
: search for multiple line comments/fred\_s*joe/
: any whitespace including newline/bugs\(\_.\)*bunny
: bugs followed by bunny anywhere in file/\c\v([^aeiou]&\a){4}
: search for 4 consecutive consonants/\%>20l\%<30lgoat
: search for goat between lines 20 and 30/^.\{-}home.\{-}\zshome/e
: match only the 2nd occurence in a line of home/^\(.*tongue.*\)\@!.*nose.*$
\v^((tongue)@!.)*nose((tongue)@!.)*$
.*nose.*\&^\%(\%(tongue\)\@!.\)*$
:v/tongue/s/nose/&/gic
'a,'bs/extrascost//gc
: trick: restrict search to between markers/integ<C-L>
: Control-L to complete term//e
: 匹配 pattern
為空則直接重用上次的邏輯進行查找/\<f\>
: 使用 <
與 >
限定詞首與詞尾, 保證只查找單詞 f
/^\n\{3}
: 查找三個空行/\s\{2,}
: 查找 2 個以上的空格/he\zsllo
: 查找 hello
并將 llo
作為匹配點進行高亮/abc\(defg\)\@!
: 只查找 abc
, 且后面不跟隨 defg
, 否則不匹配, \@!
表示 negative look-ahead assertion
, 查看幫助 help \@!
/printer_\@!
: find any printer
that is not followed by an _
/_\@<!printer
: find any printer
that is not begin with an _
`[^`]\_.\{-0,}`
: 以 `
開頭, 以 `
結尾, 且中間內容超過一個字符, 且內容可以跨行還有一種是使用 global
命令: :g/pattern/d
, 含義是對 patter 進行匹配搜索, 然后執(zhí)行命令 delete
, 也是基于查找的
:noh
: 取消查找模式的高亮匹配*
: 全文查找當前光標處單詞 (n 為向下方向)#
: 全文查找當前光標處單詞 (n 為向上方向)n
: 下一個列出的關鍵字N
: 上一個列出的關鍵字gn
: 進入面向字符的可視模式, 并選中下一項匹配gN
: 進入面向字符的可視模式, 并選中上一項匹配gUgn
: 使下一處匹配改為大寫<C-r><C-w>
: 根據當前查找模式下已經輸入的內容結合全文進行自動補全/<UP>
: 直接調用上次的查找邏輯./<DOWN>
: 直接調用下次的查找邏輯./<C-n>
: 直接調用下次的查找邏輯./<C-p>
: 直接調用上次的查找邏輯./<C-r>/
: 使用寄存器 /
將上次查找的值直接插入到當前模式中來\r
: 換行, 在 pattern 中使用\n
作為搜索串, 在string 中使用\r
作為換行命令(如果在 string 中仍然使用 \n 的話會出錯)\u
或 \l
: 把替換串中的下一個字符分別變成大寫或者小寫.~
: 用在替換串中, 代表使用上次的替換串.&
: 用在替換串, 它代表與搜索模式想匹配的整個文本, 即“重現”搜索串. 這在試圖避免重復輸入文本時很有用.\0
: 同 &
\1
: 匹配到的第一個 \(...\)
\2
: 匹配到的第二個 \(...\)
\U
: 將跟在后面的匹配串全部變成大寫\L
: 將跟在后面的匹配串全部變成小寫\E
/ \e
: end of \U
and \L
\l
: next character made lowercase\u
: next character made uppercase:[range]s/pattern/string/flags
range
: 范圍無
: 默認光標所在的行.
: 光標所在的當前行N
: 第 N 行$
: 最后一行'a
: 標記 a
所在的行(使用 ma
標記的).+1
: 當前光標的下面一行$-1
: 倒數第二行22,23
: 第22 ~ 23行1,$
: 第一行到最后一行1,.
: 第一行到當前行.,$
: 當前行到最后一行'a, 'b
: 標記 a
所在的行到 標記 b
所在的行%
: 所有行(與 1,$
等價)?str?
: 從當前位置向上搜索, 找到的第一個 str 所在的行(str 可以為正則表達式)/str/
: 從當前位置向下搜索, 找到的第一個 str 所在的行1,7
指第一行至第七行. 也可以使用 %
代表當前的文章(也可以理解為全部的行), #
代表前一次編輯的文章(基本不用)s
: 代表當前的模式為替換/
: 作為分隔符, 如果確實要替換文中的 /
, 那么可以使用 #
代替作為分隔符. 例如 :s#vi/#vim#g
, 代表替換 vi/
為 vim
pattern
: 要被替換掉的字符string
: 將要使用的字符flags
無
: 只對指定范圍內的每一行的第一個匹配項進行替換g
: global, 整行替換(基本上是必加的, 否則只會替換每一行的第一個符合字符)c
: confirm, 每次替換前會詢問e
: ignore, 忽略錯誤(默認找不到會提示 pattern not found
, 但是如果設置 vim 設置批量替換命令的話某一個項未匹配到不能影響到下一項的執(zhí)行, 可以使用此關鍵字, :silent %s/x/y/g
== :%s/x/y/ge
)i
: ignore, 不區(qū)分大小寫I
: 區(qū)分大小寫在表達式中可以使用 \(
與 \)
將表達式括起來, 然后既可在后面使用 \1
\2
來依次訪問由 \(
與 \)
包圍起來的內容.
例: :s/\(\w\+\)\s\+\(\w\+\)/\2\t\1
表示將 data1 data2 修改為 data2 data1
r
: 進入單字符替換模式R
: 進入替換模式:&
: 重復上次替換:%&
: last substitute every line:%&gic
: last substitute every line confirmg%
: normal mode repeat last substituteg&
: last substitute on all lines&
: 直接使用 &
也是重復上次替換的意思:s/vi/vim/
: 只替換當前行的第一個 vi 為 vim:s/vi/vim/g
: 替換當前行的所有 vi 為 vim:%s/vi/vim/g
: 替換全文所有 vi 為 vim:%s/vi/vim/gi
: 替換全文所有 vi 為 vim, 大小寫不敏感:n,$s/vi/vim/gci
: 替換從第 n 行到結尾所有 vi 為 vim, 每次替換提示, 不區(qū)分大小寫:.,$s/vi/vim/gci
: 替換從當前行到結尾所有 vi 為 vim, 每次替換提示, 不區(qū)分大小寫:.,+3s/^/#
: 在當前行到下面三行添加 #
的注釋:g/^\s*$/d
: 刪除所有空行:g/^$/d
: 刪除所有空行:%s/\s*$//g
: 刪除行尾空格:%s/^\s*//g
: 刪除行首空格:215,237 s/\(.\)$/\1(自定義)/c
: 將 215 至 237 行尾部添加 (自定義)
:%s/^\n$//gc/
: 替換多個空行為一個空行:s:\s\+$::
: a simple regexp I use quite often to clean up a text: it drops the blanks at the end of the line.:122,250s/\(201\d*\)\.\(\d*\)\.\(\d*\)\s/\1-\2-\3_/gc
: 替換 2017.12.31
類型的字段為2017-12-31_
%s/\(\](http:.*com\/\)\(HK.*\))/\](https:\/\/a.hanleylee.com\/\2?x-oss-process=style\/WaMa)/gc
: 將[](http: ....com)
替換成 https 并且尾部帶有樣式參數:%s/\(a.*bc\)\(<.*>\)\(xy.*z\)/\3\2\1/gc
: 使用緩沖塊實現對前后區(qū)域匹配并翻轉位置(需要時再理解):%s/hello/&, world/
: 將會把hello替換成hello, wolrd:%s/.*/(&)/
: 將會把所有行用()包含起來:s/world/\U&/
: 把 world 變成 WORLD:%s ; /user1/tim;/home/time;g
: /user1/tim
改為/home/time
, 除了 /
字符外, 還可以使用除反斜桿 \
, 雙引號"
, 和豎直線 |
之外的任何非字母表, 非空白字符作為分隔符, 在對路徑名進行修改時, 這點尤其便利:s
: 與 :s//~/
相同, 重復上次替換%s/\<child\>/children/g
: 保證在 child 是個完整單詞的情況下進行替換:g/mg[ira]box/s/box/square/g
: 將 mgibox routine, mgrbox routine, mgabox routine,
中的 box 換為 square:%s/fred/joe/igc
: general substitute command:%s//joe/igc
: substitute your last replacement string:%s/~/sue/igc
: substitute your last replacement string:%s/\r//g
: delete DOS return ^M
:%s/\r/\r/g
: turn DOS return ^M
into real returns:%s= *$==
: delete end of line blanks:%s= \+$==
: Same thing:%s#\s*\r\?$##
: Clean both trailing spaces AND DOS returns:%s#\s*\r*$##
: same thing:%s/^\n\{3}//
: delete blocks of 3 empty lines:%s/^\n\+/\r/
: compressing empty lines:%s#.*\(\d\+hours\).*#\1#
: delete all but memorised string:%s#><\([^/]\)#>\r<\1#g
: split jumbled up XML file into one tag per line [N]:%s/</\r&/g
: simple split of html/xml/soap [N]:%s#<[^/]#\r&#gic
: simple split of html/xml/soap but not closing tag [N]:%s#<[^/]#\r&#gi
: parse on open xml tag [N]:%s#\[\d\+\]#\r&#g
: parse on numbered array elements [1] [N]ggVGgJ
: rejoin XML without extra spaces (gJ) [N]:%s=\\n#\d=\r&=g
: parse PHP error stack [N]:%s#^[^\t]\+\t##
: Delete up to and including first tab [N]:'a,'bg/fred/s/dick/joe/igc
: VERY USEFUL:%s= [^ ]\+$=&&=
: duplicate end column:%s= \f\+$=&&=
: Dupicate filename:%s= \S\+$=&&
: usually the same:%s#example#& = &#gic
: duplicate entire matched string [N]:%s#.*\(tbl_\w\+\).*#\1#
: extract list of all strings tbl_* from text [NC]:s/\(.*\):\(.*\)/\2 : \1/
: reverse fields separated by ::%s/^\(.*\)\n\1$/\1/
: delete duplicate lines:%s/^\(.*\)\(\n\1\)\+$/\1/
: delete multiple duplicate lines [N]:%s/^.\{-}pdf/new.pdf/
: delete to 1st occurence of pdf only (non-greedy):%s#^.\{-}\([0-9]\{3,4\}serial\)#\1#gic
: delete up to 123serial or 1234serial [N]:%s#\<[zy]\?tbl_[a-z_]\+\>#\L&#gc
: lowercase with optional leading characters:%s/<!--\_.\{-}-->//
: delete possibly multi-line comments:s/fred/<c-r>a/g
: sub "fred" with contents of register "a":s/fred/<c-r>asome_text<c-r>s/g
:s/fred/\=@a/g
: better alternative as register not displayed:s/fred/\=@*/g
: replace string with contents of paste register:%s/\f\+\.gif\>/\r&\r/g | v/\.gif$/d | %s/gif/jpg/
:%s/a/but/gie|:update|:next
: then use @: to repeat:%s/goat\|cow/sheep/gc
: ORing (must break pipe):'a,'bs#\[\|\]##g
: remove [] from lines between markers a and b [N]:%s/\v(.*\n){5}/&\r
: insert a blank line every 5 lines [N]:s/__date__/\=strftime("%c")/
: insert datestring:inoremap \zd <C-R>=strftime("%d%b%y")<CR>
: insert date eg 31Jan11 [N]:%s:\(\(\w\+\s\+\)\{2}\)str1:\1str2:
:%s:\(\w\+\)\(.*\s\+\)\(\w\+\)$:\3\2\1:
:%s#\<from\>\|\<where\>\|\<left join\>\|\<\inner join\>#\r&#g
:redir @*|sil exec 'g#<\(input\|select\|textarea\|/\=form\)\>#p'|redir END
:nmap ,z :redir @*<Bar>sil exec 'g@<\(input\<Bar>select\<Bar>textarea\<Bar>/\=form\)\>@p'<Bar>redir END<CR>
:%s/^\(.\{30\}\)xx/\1yy/
: substitute string in column 30 [N]:%s/\d\+/\=(submatch(0)-3)/
: decrement numbers by 3:g/loc\|function/s/\d/\=submatch(0)+6/
: increment numbers by 6 on certain lines only:%s#txtdev\zs\d#\=submatch(0)+1#g
:%s/\(gg\)\@<=\d\+/\=submatch(0)+6/
: increment only numbers gg\d\d by 6 (another way):let i=10 | 'a,'bg/Abc/s/yy/\=i/ |let i=i+1
: convert yy to 10,11,12 etc:let i=10 | 'a,'bg/Abc/s/xx\zsyy\ze/\=i/ |let i=i+1
# convert xxyy to xx11,xx12,xx13:%s/"\([^.]\+\).*\zsxx/\1/
:vmap <leader>z :<C-U>%s/\<<c-r>*\>/
:'a,'bs/bucket\(s\)*/bowl\1/gic
:%s,\(all/.*\)\@<=/,_,g
: replace all / with _ AFTER "all/"
:s#all/\zs.*#\=substitute(submatch(0), '/', '_', 'g')#
:s#all/#&^M#|s#/#_#g|-j!
: Substitute by splitting line, then re-joining:%s/.*/\='cp '.submatch(0).' all/'.substitute(submatch(0),'/','_','g')/
: Substitute inside substitute:%s/home.\{-}\zshome/alone
: substitute only the 2nd occurence of home in any line:%s/.*\zsone/two/
: substitute only the last occurrence of one替換時系統(tǒng)會對用戶進行詢問, 有 (y/n/a/q/1/^E/^Y
)
y
: 表示同意當前替換n
: 表示不同意當前 替換a
: 表示替換當前和后面的并且不再確認q
: 表示立即結束替換操作1
: 表示把當前的替換后結束替換操作;^E
: 向上滾屏^Y
: 向下滾屏,global 語法有兩種
:[range]g:/{pattern}/[cmd]
: 在 range 內搜索 pattern, 如果符合要求就執(zhí)行 cmd:g/pattern1/, /pattern2/[cmd]
: 在 /p1/
, p2/
之間執(zhí)行 cmd:g/re/d
: 刪除所有匹配到 re
的行:g/re/p
: 打印所有匹配到 re
的行:g//d
: 使用上次的查找結果進行匹配然后刪除:g/^$/,/./-j
: reduce multiple blank to a single blank:10,20g/^/ mo 10
: reverse the order of the lines starting from the line 10 up to the line 20.:'a,'b g/^Error/ . w >> errors.txt
: in the text block marked by 'a
and 'b
find all the lines starting with Error and copy (append) them to errors.txt
file. Note: . (current line address) in front of the w
is very important, omitting it will cause :write
to write the whole file to errors.txt
for every Error line found.:g/^Error:/ copy $ | s /Error/copy of the error/
: will copy all Error line to the end of the file and then make a substitution in the copied line. Without giving the line address :s
will operate on the current line, which is the newly copied line.:g/^Error:/ s /Error/copy of the error/ | copy $
: here the order is reversed: first modify the string then copy to the end.:v/re/d
: vglobal 的反面, 只保留匹配到 re
的行:g/TODO/yank A
: 將結果匹配到 TODO
的行復制到寄存器 a
的原內容尾部:g/TODO/t$
: 將結果匹配到 TODO
的行復制到本緩沖區(qū)的尾部:g/{/.+1,/}/-1 sort
: 會在每個 {
開始找, 然后在之后一直執(zhí)行到 }
為止, 進行排序:g/{/sil.+1,/}/-1 >
: 會在每個 {
開始找, 然后在之后一直執(zhí)行到 }
為止, 進行縮進 (加入 sil 是為了屏蔽提示信息):g/ 從這里刪除 /.,$ d
: 從內容中搜出的第一個 從這里刪除
開始, 一直刪除到文章結尾:g/^\(.*\)$\n\1$/d
: 去除重復行:g/\%(^\1$\n\)\@<=\(.*\)$/d
: 去除重復行:g/\%(^\1\>.*$\n\)\@<=\(\k\+\).*$/d
: 去除重復行:g/gladiolli/#
: display with line numbers:g/gred.*joe.*dick/
: display all lines fred, joe & dick:g/\<fred\>/
: display all lines fred but not freddy:g/^\s*$/d
: delete all blank lines:g!/^dd/d
: delete lines not containing string:v/^dd/d
: delete lines not containing string:g/joe/,/fred/d
: not line based:g/joe/,/fred/j
: join lines:g/-----/.-10,.d
: delete string & 10 previous lines:g/{/ ,/}/- s/\n\+\r/g
: delete empty lines but only between {...}
:v/\S/d
: delete empty lines:v/./,/./-j
: compress empty lines:g/^$/,/./-j
: compress empty lines:g/<input\|<form/p
:ORing:g/^/put_
: double space file (pu = put):g/^/m0
: reverse file(m = move):g/^/m$
: no effect!:'a,'bg/^/m'b
: reverse a section a to b:g/^t.
: duplicate every line:g/fred/t$
: copy(transfer) lines matching fred to EOF:g/stage/t'a
: copy(transfer) lines matching stage to marker a:g/^chapter/t.|s/./-/g
: automatically underline selecting headings:g/\(^I[^^I]*\)\{80}/d
: delete all lines containing at least 80 tabs:g/^/ if line('.')%2|s/^/zz /
: perform a substitute on every other line:'a,'bg/somestr/co/otherstr/
: co(py) or mo(ve):'a,'bg/str1/s/str1/&&&/|mo/str2/
: as above but also do a substitution:%norm jdd
: delete every other line:.,$g/^\d/exe "norm! \<c-a>"
: increment numbers " incrementing numbers (type <c-a>
as 5 characters):'a,'bg/\d\+/norm! ^A
: increment numbers:g/fred/y A
: append all lines fred to register a:g/fred/y A | :let @*=@a
: put into paste buffer:g//y A | :let @*=@a
: put last glob into paste buffer [N]:let @a=''|g/Barratt/y A |:let @*=@a
:'a,'bg/^Error/ . w >> errors.txt
: filter lines to a file (file must already exist):g/./yank|put|-1s/'/"/g|s/.*/Print '&'/
: duplicate every line in a file wrap a print '' around each duplicate:g/^MARK$/r tmp.txt | -d
: replace string with contents of a file, -d deletes the "mark":g/<pattern>/z#.5
: display with context:g/<pattern>/z#.5|echo "=========="
: display beautifully:g/|/norm 2f|r*
: replace 2nd | with a star:nmap <F3> :redir @a<CR>:g//<CR>:redir END<CR>:new<CR>:put! a<CR><CR>
:'a,'bg/fred/s/joe/susan/gic
: can use memory to extend matching:/fred/,/joe/s/fred/joe/gic
: non-line based (ultra):/biz/,/any/g/article/s/wheel/bucket/gic
: non-line based [N]:/fred/;/joe/-2,/sid/+3s/sally/alley/gIC
:g/^/exe ".w ".line(".").".txt"
: create a new file for each line of file eg 1.txt,2.txt,3,txt etc:.g/^/ exe ".!sed 's/N/X/'" | s/I/Q/
: chain an external command:g/^$/;/^$/-1!sort
: Sort each block (note the crucial ;)d/fred/
: delete until fredy/fred/
: yank until fredc/fred/e
: change until fred endv12|
: visualise/change/delete to column 12'a' =~# '\a'
: 匹配返回 1, 不匹配返回 0, 不忽略大小寫'a' =~? '\a'
: 同上, 但忽略大小寫'a'!~# '\a'
: 匹配返回 0, 不匹配返回 1, 不忽略大小寫'a'!~? '\a'
: 同上, 但忽略大小寫substitute( {expr}, {pat}, {sub}, {flags})
: 使用 flags
, 替換 expr
里面的 pat
(即 pattern 表示的正則) 為 sub
match( {expr}, {pat}[, {start}[, {count}]])
: 返回 pat
在 expr
里面所匹配的位置, 可設置開始位置和重復次數matchend( {expr}, {pat}[, {start}[, {count}]])
: 跟 match
函數一樣, 但是返回最后一個字符的匹配位置matchlist({expr}, {pat}[, {start}[, {count}]])
: 返回匹配的列表, 第一項是完整匹配, 后面是其它子匹配項matchstr({expr}, {pat}[, {start}[, {count}]])
: 返回 expr
里面 pat
所匹配的字符串, 無匹配返回空字符串以下由最高優(yōu)先級至最低進行排列
Precedence | Regexp | Description |
---|---|---|
1 | \( \) |
grouping |
2 | \=,\+,*,\{n} etc. |
quantifiers |
3 | abc\t\.\w |
sequence of characters/ metacharacters, not containing quantifiers or grouping operators |
4 | | |
alternation |
多文件操作的基礎是一定要 設置好工作目錄, 因為添加文件到操作列表是以當前路徑下的文件進行判斷篩選的, 設置當前路徑可使用以下方式:
:cd path
NERDTree
插件的 cd
命令netrw
插件的 cd
命令.vimrc
中設置 set autochair
自動切換當前工作路徑vimgrep /pattern/[g][j] <range>
vimgrep
: 批量查找命令, 其后可直接加 !
代表強制執(zhí)行. 也可以使用lvimgrep
, 結果顯示在 list 中patten
: 需要查找的內容, 支持正則表達式, 高級用法見元字符g
: 如果一行中有多個匹配是否全部列出j
: 搜索完后直接定位到第一個匹配位置range
: 搜索的文件范圍%
: 在當前文件中查找**/*.md
: 在當前目錄即子目錄下的所有 .md 文件中*
: 當前目錄下查找所有(不涉及子目錄)**
: 當前目錄及子目錄下所有*.md
: 當前目錄下所有.md 文件**/*
: 只查找子目錄查找的結果使用 quick-fix
來進行展示, 可使用 :copen
查看所有結果項并進行相應跳轉, 具體操作參考 神級編輯器 Vim 使用-操作篇
:vimgrep /hello/g **
: 在當前目錄及子目錄下的所有文件內查找 hello
字符串quickfix-list 是一個完整的窗口, 可以移動上下光標, 按下 enter 進行打開文件
location-list 只是一個局部的顯示區(qū)域, 只能簡單顯示查找結果的信息, 目前看來沒有必要使用此選項
多文件替換所依賴的是 vim 中的參數列表概念, 這里僅對流程命令進行演示, 具體的參數列表操作參考 神級編輯器 Vim 使用-操作篇
:args
: 顯示當前的所有參數列表:args *.md aa/**/*.md
表示添加子文件夾下的 md
文件及 aa
文件夾下的和其子文件夾下的 md
文件到參數列表中:argdo %s/oldword/newword/egc | update
: 對所有存在參數列表中的文件執(zhí)行命令, s
代表替換, %
指對所有行進行匹配, g
代表整行替換(必用), e
指使用正則表達式, c
代表每次替換前都會進行確認, update
表示對文件進行讀寫:argdo %s/!\[.*\]/!\[img\]/gc
: 將所有參數列表中的以 ![
開頭, 以 ]
結尾的所有字段改為 [img]
:argdo write
: 將所有參數列表中的內容進行緩沖區(qū)保存我的 vim 配置倉庫: HanleyLee/dotvim
本文作者 Hanley Lee, 首發(fā)于 閃耀旅途, 如果對本文比較認可, 歡迎 Follow
聯(lián)系客服