vim 删除重复部分的行 vim 技巧

g/\%(^\1\>.*$\n\)\@<=\(\k\+\).*$/d
重复的部分不是全行,而是kerword部分(:h 'iskeyword'),遇到空格,-什么的就终止,

 

搜索
/joe/e : 设置光标到匹配"joe"的末尾
/joe/e+1 : 设置光标到匹配"joe"的末尾再后移一位
/joe/s-2 : 设置光标到匹配"joe“的开头再前移两位
/joe/-2 : 设置光标到匹配"joe“的行再向上移两行的开头
/^joe.*fred.*bill/ : 匹配以“joe”开头且"joe"到"fred"到"bill"之间没有字符或者有字符
/^[A-J]\+/ : 搜索以'A'到’J‘间的一个或者多个字母组合的开头
/begin\_.*end : 多行匹配,begin和end可以不在同一行,因为\_.包括\n
/fred\_s*joe/i : 可以是任何空白字符包括空格,\t,\n等等
/fred\|joe : 搜索fred或者joe
/.*fred\&.*joe : 搜索同时包括fred跟joe的行。注意,\&表示“且”,所以行中不一定要求fred在joe前
/\/i : 搜索独立的单词fred
/\<\d\d\d\d\> : 搜索独立的4位数字
/\D\d\d\d\d\D : 搜索6位字符串,中间4位数字,首尾两位不能为数字
/\<\d\{4}\> : 同/\<\d\d\d\d\>

" 查找空行
/^\n\{3} : 匹配3个连续的空行

" 使用正则表达式组查找
/\(fred\).*\(joe\).*\2.*\1

" 正则表达式重复
/^\([^,]*,\)\{8}

" visual searching
:vmap // y/" :可视模式下的键盘映射。把//映射成“查找当前选中的文本”,y表示将当前选中内容拷贝到"寄存器中,然后/开始查找,查找内容是后面的输 入,表示ctrl-r,是回车
:vmap // y/=escape(@",'\\/.*$^~[]') :包括空白字符,加上,是为了在屏幕最下面的命令行不显示该命令。

" \zs 和 \ze 匹配原 :h /\zs
/<\zs[^>]*\ze> : 匹配尖括号中的内容

" 零宽度匹配 :h /\@=
/<\@<=[^>]*>\@= : 匹配<>标签中的内容,而忽略<和>本身
/<\@<=\_[^>]*>\@= : 和上例相比,差别在于允许跨行

" 多行查找 \_ 的意思是包括换行符
/ : 匹配结尾的所有内容
/fred\_s*joe/i : 匹配fred开始到joe,之间没有任何字符或者是有空白字符
/bugs\(\_.\)*bunny : 匹配所有bugs到bunny的字符串
:h \_ : help

" 查找函数声明,nmap为normal模式下的键盘映射
:nmap gx yiw/^\(sub\function\)\s\+" : yiw表示将当前所在单词拷贝到寄存器"中,表示|,即sub或者function

" 查找多个文件
:bufdo /searchstr/ : 在多个文件缓冲区里执行查找

" 更好的多文件查找定位方法
:bufdo %s/searchstr/&/gic : 在多个文件缓冲区里查找,按下n停止

" 怎样不使用 / 来查找网址
?http://www.vim.org/ : 向上查找

" 查找指定字符以外的字符串
/\c\v([^aeiou]&\a){4} :查找4个辅音字母,\c表示忽略大小写,\v表示后面所有ascii字符,除了0-9,a-z,A-Z以及_,均有特殊含义,就是所谓非常magic, 而\V表示后面的内容中只有反斜杠\含有特殊含义,就是所谓的非常不magic,(和)中间的内容,表示首先不能是aeiou,但是必须是\a(字母)。

----------------------------------------
" 替换
:%s/fred/joe/igc : 普通替换命令
:%s/\r//g : 删除 DOS 的换行符 ^M

" 你的文本文件是否乱七八糟的排成一行?使用如下命令
:%s/\r/\r/g : 转换 DOS 回车符 ^M 为真正的回车符
:%s= *$== : 删除行尾空白
:%s= \+$== : 同上
:%s#\s*\r\?$## : 删除尾部空白和dos换行符
:%s#\s*\r*$## : 同上

" 删除空行
:%s/^\n\{3}// : 删除连续3个空行
:%s/^\n\+/\r/ : 压缩空行,多个替换为一个
%s#<[^>]\+>##g : 删除html的tag部分

" 如果你只想学一招,那么就是这个了
:'a,'bg/fred/s/dick/joe/igc : 非常有用
# ''a,''b指定一个范围:mark a ~ mark b
# g//用一个正则表达式指出了进行操作的行必须可以被fred匹配
# 看后面,g//是一个全局显示命令
# s/dick/joe/igc则对于这些满足条件的行进行替换

" 复制最后一个字段
:%s= [^ ]\+$=&&= : 复制最后一个字段
:%s= \f\+$=&&= : 一样
:%s= \S\+$=&& : 一样!

" 记忆(反向引用)
:s/\(.*\):\(.*\)/\2 : \1/ : 将两个字段颠倒
:%s/^\(.*\)\n\1$/\1/ : 删除重复行

" 非贪婪匹配 \{-}
:%s/^.\{-}pdf/new.pdf/ : 将第一个pdf的名字换为new.pdf

" 使用可选原子 \?
:%s#\<[zy]\?tbl_[a-z_]\+\>#\L&#gc : 匹配tbl前面没有字母,或者z和y中的某一个字母,然后将所有的字母变为小写

" 跨越尽量多的行
:%s/// : 删除多行注释
:help /\{-} : 查看非贪婪匹配的更多帮助

" 使用寄存器替换
:s/fred/a/g : 将fred替换为寄存器a里的内容,为按下Ctrl与r,然后输入a后,寄存器a的内容会出现在命令行
:s/fred/asome_texts/g
:s/fred/\=@a/g : 与第一条的作用相同,但是更优雅一些,因为不会在命令行显示寄存器的内容

" 在一行里写多种命令
:%s/\f\+\.gif\>/\r&\r/g | v/\.gif$/d | %s/gif/jpg/ :将所有带有.gif的行,前后均加入一个空行;将不带有.gif字样的行全部删除;将所有行中的gif换成jpg;注意三条语句,一旦某一条失败,则不 执行下面的语句
:%s/a/but/gie|:update|:next : 首先,将当前文件中的所有a变为but;然后保存文件;最后进入下一个文件缓存区。如果有多个文件需要如此处理,可以考虑使用 @:来重复,@:的意义是:执行上一次的命令行命令n次。

" 或运算
:%s/suck\|buck/loopy/gc : 替换suck或者buck为loopy(这里|不是管道)

" 调用vim函数
:s/__date__/\=strftime("%c")/ : 将__date__替换成当前日期,使用strftime函数。注意\=表示后面是表达式,结果可能是2008-1-3 17:59:46

" 处理字段,替换所有在第三个字段中的str1为str2
:%s:\(\(\w\+\s\+\)\{2}\)str1:\1str2:

" 交换第一列跟第四列
:%s:\(\w\+\)\(.*\s\+\)\(\w\+\)$:\3\2\1:

" 过滤form中的内容放在寄存器里
:redir @*|sil exec 'g#<\(input\|select\|textarea\|/\=form\)\>#p'|redir END : redir是将执行的结果重定向到后面的*寄存器中,sil是silent
:nmap ,z :redir @*sil exec'g@<\(input\select\textarea\/\=form\)\>@p'redirEND : 普通模式下,敲入,z,命令行执行redir @*|sil exec'g@<\(input\|select\|textarea\|/\=form\)\>@p'|redir END

" 一位以上的数字减3(带进位,这个命令挺有趣)
:%s/\d\+/\=(submatch(0)-3)/

" 包含loc或者functions的行中的数字加6
:g/loc\|function/s/\d/\=submatch(0)+6/

" 比上面更好的方法
:%s#txtdev\zs\d#\=submatch(0)+1#g : \zs表示是s要匹配的的内容的开头
:h /\zs 查看帮助

" 前缀为gg的数字加6
:%s/\(gg\)\@<=\d\+/\=submatch(0)+6/
:h zero-width 查看帮助

" 替换一个特定字符串为数字
:let i=10 | 'a,'bg/Abc/s/yy/\=i/ |let i=i+1 # 将yy转换成10,11,12等等

" 比上面的更精确
:let i=10 | 'a,'bg/Abc/s/xx\zsyy\ze/\=i/ |let i=i+1 # 将xxyy 转换成 xx11(第一行),xx12(第二行),xx13(第三行)

" 发现要替换的文本,放入内存,然后使用\zs来简化替换
:%s/"\([^.]\+\).*\zsxx/\1/ : \zs表示是s要匹配的的内容的开头

" 将光标下的单词,放入替换语句的LHS中
:nmap z:%s#\<=expand("")\># :在没有定义mapleader时为\,定义后为mapleader的值。LHS指的是s替换后面,被替换的内容(在左手 边)。普通模式下,如果光标下为abc,则输入\z两个字符,结果命令行出现:%s#\#,然后你就可以接着输入替换后的内容 了。

" 将可视模式下的高亮文本,放入替换语句的LHS中
:vmap z :%s/\<*\>/

----------------------------------------
" 以下功能相同,在替换语句内部进行替换
" 每行的一部分中,只执行多个单字符的替换
:%s,\(all/.*\)\@<=/,_,g : 用_替换all后的所有/,all/中的/不变

" 功能同上
:s#all/\zs.*#\=substitute(submatch(0), '/', '_', 'g')#

" 通过将一行分开,然后重新组合,达到替换的效果
:s#all/#&^M#|s#/#_#g|-j! : 在windows下使用了mswin的模式,所以^M得输入为\r,呵呵

" 在替换命令中使用替换
:%s/.*/\='cp '.submatch(0).' all/'.substitute(submatch(0),'/','_','g')/: 不work,因为all/后面的/和s所有的/有重复。所以我改为 :%s#.*#\='cp '.submatch(0).'all/'.substitute(submatch(0),'/','_','g')#

----------------------------------------
" 全局显示命令
:g/gladiolli/# : 查找并显示匹配的行号
:g/fred.*joe.*dick/ : 显示所有含有 fred,joe & dick的行
:g/\/ : 显示单一单词fred
:g/^\s*$/d : 删除所有空行
:g!/^dd/d : 删除不含字符串''dd''的行
:v/^dd/d : 同上
:g/fred/,/joe/d : 删除所有的从fred到joe
:g/-------/.-10,.d : 以-------为标记删除之前的10行
:g/{/ ,/}/- s/\n\+/\r/g : 删除 {...}之间的空行
:v/\S/d : 删除空行
:v/./,/./-j : 压缩空行
:g/^$/,/./-j : 同上
:g/:g/^/put_ : 双倍行宽 (pu = put)
:g/^/m0 : 颠倒文件 (m = move)
:'a,'bg/^/m'b : 颠倒选中的 a 到 b
:g/^/t. : 重复行
:g/fred/t$ : 拷贝行从fred到结尾
:g/stage/t'a : 拷贝行从stage 到 marker a(a为标记的位置)
:g/\(^I[^^I]*\)\{80}/d : 删除最少包含80个tab的行,注意:^I的输入方法是ctrl-v, ctrl-i

" 隔行替换
:g/^/ if line('.')%2|s/^/zz /

" 查找标记a与b间所有包含"somestr"的行,并全部复制到第一个包含"otherstr"的行后
:'a,'bg/somestr/co/otherstr/ : co(py) or mo(ve)

" 与上面相同,但是多做了一次替换
:'a,'bg/str1/s/str1/&&&/|mo/str2/
:%norm jdd : 隔行删除

" 增加数字 (键入 ) : 在MS-Windows中已经被定义为全选
:.,$g/^\d/exe "norm! \": 增加从当前行首到结尾的数字
:'a,'bg/\d\+/norm! ^A : 增加数字

" 保存全局命令的结果 (注意必须使用添加模式) 你需要使用 qaq 清空寄存器a.
" 将结果存储到寄存器a或者复制缓存区中
:g/fred/y A : 添加带有fred的行到寄存器到a
:g/fred/y A | :let @*=@a : 除了同上外,还将寄存器a的内容,放入复制缓冲区
:let @a=''|g/Barratt/y A |:let @*=@a
:'a,'b g/^Error/ . w >> errors.txt : 将查找内容放入一个文件 (文件必须存在)

" 复制每一行,然后在复制出来的每一行左侧加上一个 print '复制出来的内容'
:g/./yank|put|-1s/'/"/g|s/.*/Print '&'/

" 用文件中的内容替换字符串,-d 表示删除上面的一行
:g/^MARK$/r tmp.ex | -d

" 优雅地显示
:g//z#.5 : 带有上下文一并显示
:g//z#.5|echo "==========" : 优雅地显示

" 将g//和普通模式下的命令结合起来
:g/|/norm 2f|r* : 将第二个|替换为*号

" 将前面g命令的输出,发送到新窗口中
:nmap :redir @a:g//:redir END:new:put! a

----------------------------------------
" 全局命令和替换命令联姻 (强大的编辑能力)
:'a,'bg/fred/s/joe/susan/gic : 可以使用反向引用来匹配
:g/fred/,/joe/s/fred/joe/gic : 非行模式

----------------------------------------
" 先找fred,然后找joe
:/fred/;/joe/-2,/sid/+3s/sally/alley/gIC : 最后这一个C,手册中都没有,估计是c

----------------------------------------
" 为每一行生成一个文件,文件名从1.txt开始,依次为1.txt,2.txt,3,txt等等
:g/^/exe ".w ".line(".").".txt"

----------------------------------------
" 绝对精华

----------------------------------------
* # g* g# : 查找当前光标下的单词(单个单词) () (向前/向后)
% : 匹配括号 {}[]()
. : 重复上次操作
@: : 重复上次的命令
matchit.vim : 适%能匹配

你可能感兴趣的:(vim 删除重复部分的行 vim 技巧)