<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://jackxiang.com/post//</link>
<title><![CDATA[vi高级命令]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Wed, 02 Jan 2008 02:37:58 +0000</pubDate> 
<guid>http://jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	1.交换两个字符位置<br/>xp<br/>其实就是删除光标当前字符(x)，然后再将缓存的字符贴出(p)<br/><br/>2.上下两行调换<br/>ddp<br/>实际就是(dd)删除当前行，(p)后即将缓存的行贴出<br/><br/>3.把文件内容反转<br/>:g/^/m0/ (未通过)<br/>这个貌似没写全啊<br/><br/>4.上下两行合并 <br/>J<br/>实用性：高，shift+j<br/><br/>5.删除所有行 <br/>dG<br/>错!(d)为删除，(shift+g)到文件尾，因此这命令效用为从光标处删除至文件尾<br/>那么删除到文首呢？对了，如果知道gg可以将光标移至文首，那么dgg便是删除到文首了<br/>类似的还有：<br/>dw -- 删到词尾<br/>db -- 删到词头<br/>daw -- 删除光标所在词（较有用）<br/><br/><br/>如果你用 "c" 代替 "d"，这会变成修改命令；而改用 "y"，则变成拷贝命令，等等等等。<br/>6.从当前位置删除到行尾<br/>d$<br/>(d)删除，$ (即 shift+4)为行尾，^（ 即 shift+6)为行头，依此类推，d^删除至行头<br/>更为简洁的命令为D，对了，就是shift+d，就这么简单<br/><br/>7.从当前位置复制到行尾<br/>y$ 如果要粘贴到其他地方 p 就可以了<br/>同上<br/><br/>由于vi 是建立在 EX 上的 所以 当键入 : 时就来到了 EX 命令状态 <br/><br/>8.<br/>:ab string strings <br/>例如 ":ab usa United States of America" ,<br/>当你在文件里插入 usa 时 <br/>United States of America 就蹦出来了<br/>其实执行的是":abbreviate"命令，用":unabbreviate"命令解除缩写，要删除全部缩写用":abclear"<br/><br/>9.<br/>:map keys new_seq <br/>定义你当前 键盘命令 <br/>键映射，我前面的tips有用到<br/><br/>10.<br/>:set [all] <br/>vi or ex 的编辑状态<br/>如 显示每行 :set nu <br/>set，就是set，不显示行号":se nonu"<br/><br/>11.<br/>在命令状态下，nyy表示拷贝从光标行起的下n行内容，p表示paste,可刚复制的内容粘贴在光标处的<br/>下面。 <br/>讲的太不清楚了，n用数字代替，即将后面的指令重复执行n次，yy为复制，nyy复制n行<br/><br/>12.<br/>单个字符替换用r，覆盖多个字符用R，用多个字符替换一个字符用s，整行替换用S <br/>实用性：高，S等于我常用的cc或C<br/><br/>13.<br/>:%s/old_word/new_word/g<br/>这个指令是于在整个文件中替换特定字符串 <br/>替换，用法是这样：":起始行,结束行s/搜索串/替换串/gc" 从起始行到结束行，把所有的搜索串替换为替换串，最后那个"c"为开启交互式替换，%为全文<br/><br/>14.光标控制<br/>k:上移 nk 上移n行<br/>j:下移 nj 下移n行<br/>光标移动，还有h：左移 &nbsp;l：右移，不过我更喜欢用上、下、左、右，嘿嘿<br/><br/>将光标移到第n行，按下 mk<br/>将光标移到第m行，按下 "ay'k<br/>即将第n到m的行存到a寄存器，以此类推，b，c........寄存器等<br/>这样就可以将你常用的需要复用的内容粘贴到不同的寄存器中以备用<br/>想粘贴到某处，直接将光标移到某地，按下 'ap 即可,以此类推，b，c........寄存器等<br/><br/>在当前屏幕中<br/>H 跳到第一行<br/>M 跳到中间一行<br/>L 跳到最后一行 <br/>当前屏幕的光标控制技巧，助记方法为:Head、Middle、Last<br/><br/>15.<br/>表8-2 删除命令<br/>删除命令操作<br/>d l 删除当前字符（与x命令功能相同）<br/>d 0 删除到某一行的开始位置<br/>d ^ 删除到某一行的第一个字符位置（不包括空格或TA B字符）<br/>d w 删除到某个单词的结尾位置<br/>d 3 w 删除到第三个单词的结尾位置<br/>d b 删除到某个单词的开始位置<br/>d W 删除到某个以空格作为分隔符的单词的结尾位置<br/>d B 删除到某个以空格作为分隔符的单词的开始位置<br/>d 7 B 删除到前面7个以空格作为分隔符的单词的开始位置<br/>d） 删除到某个语句的结尾位置<br/>d 4） 删除到第四个语句的结尾位置<br/>d（ 删除到某个语句的开始位置<br/>d &#125; 删除到某个段落的结尾位置<br/>d &#123; 删除到某个段落的开始位置<br/>d 7 &#123; 删除到当前段落起始位置之前的第7个段落位置<br/>d d 删除当前行<br/>d /t e x t 删除从文本中出现" t e x t"中所指定字样的位置，一直向前直到下一个该字样所出现的<br/>位置（但不包括该字样）之间的内容<br/>d fc 删除从文本中出现字符"c"的位置，一直向前直到下一个该字符所出现的位置（包括<br/>该字符）之间的内容<br/>d tc 删除当前行直到下一个字符" c"所出现位置之间的内容<br/>D 删除到某一行的结尾<br/>d $ 删除到某一行的结尾<br/>5 d d 删除从当前行所开始的5行内容<br/>d L 删除直到屏幕上最后一行的内容<br/>d H 删除直到屏幕上第一行的内容<br/>d G 删除直到工作缓存区结尾的内容<br/>d 1 G 删除直到工作缓存区开始的内容<br/><br/>修改命令操作<br/>c l 更改当前字符<br/>c w 修改到某个单词的结尾位置<br/>c 3 w 修改到第三个单词的结尾位置<br/>c b 修改到某个单词的开始位置<br/>c W 修改到某个以空格作为分隔符的单词的结尾位置<br/>c B 修改到某个以空格作为分隔符的单词的开始位置<br/>c 7 B 修改到前面7个以空格作为分隔符的单词的开始位置<br/>c 0 修改到某行的结尾位置<br/>c） 修改到某个语句的结尾位置<br/>c 4） 修改到第四个语句的结尾位置<br/>c（ 修改到某个语句的开始位置<br/>c &#125; 修改到某个段落的结尾位置<br/>c &#123; 修改到某个段落的开始位置<br/>c 7 &#123; 修改到当前段落起始位置之前的第7个段落位置<br/>c tc 修改当前行直到下一个字符c所出现位置之间的内容<br/>C 修改到某一行的结尾<br/>c c 修改当前行<br/>5 c c 修改从当前行所开始的5行内容<br/><br/>.重复上一次修改！ <br/><br/>表8-4 替换命令<br/>替换命令操作<br/>s 将当前字符替换为一个或多个字符<br/>S 将当前行替换为一个或多个字符<br/>5 s 将从当前字符开始的5个字符替换为一个或多个字符<br/><br/>vi替换使用规则：<br/>:g/s1/s/s2/s3/g<br/>第一个g表示对每一个包括s1的行都进行替换，第二个g表示对每一行包括s1的行所有的s2都用s3替换<br/>s表示替换，s2是要被替换的字符串，他可以和s1相同（如果相同的话用//代替），s3是替换字符串 <br/><br/><br/>16.<br/>fx<br/>往右移动到 x 字符上<br/>Fx<br/>往左移动到 x 字符上<br/>tx<br/>往右移动到 x 字符前<br/>Tx<br/>往左移动到 x 字符后<br/>（注意：以上四个命令中，其中x是键入的字符）<br/>;<br/>分号，配合 f 和 t 使用，重复一次 <br/>,<br/>逗号，配合 f 和 t 使用，反方向重复一次<br/>如果不结合；与,很不好用，nfx为移到第n个x字符上<br/><br/>17. vi 环境选项 Solaris ksh<br/><br/>noautoindent nomodelines noshowmode<br/>autoprint nonumber noslowopen<br/>noautowrite nonovice tabstop=8<br/>nobeautify nooptimize taglength=0<br/>directory=/var/tmp paragraphs=IPLPPPQPP LIpplpipnpbtags=tags /usr/lib/tags<br/>noedcompatible prompt tagstack<br/>noerrorbells noreadonly term=vt100<br/>noexrc redraw noterse<br/>flash remap timeout<br/>hardtabs=8 report=5 ttytype=vt100<br/>noignorecase scroll=11 warn<br/>nolisp sections=NHSHH HUuhsh+c window=23<br/>nolist shell=/bin/ksh wrapscan<br/>magic shiftwidth=8 wrapmargin=0<br/>mesg noshowmatch nowriteany<br/><br/>For C-Shell:<br/>setenv EXINIT "set nu"<br/>For Bourne or Korn Shell:<br/>EXINIT="set nu"; export EXINIT <br/>For Korn Shell Only (alternate method): <br/>typeset -x EXINIT="set nu"<br/>在 .profile 里设置 vi 的环境选项 , 以上均测试过 <br/>以上的查阅vim帮助文档，太多了不一一解释了<br/><br/>18.标记文本<br/><br/>　　mchar　　 用字母char标记当前光标的位置<br/>　　`char 　　移至char所标记处<br/>　　'char　　 移至char标记所在行的开头处<br/>　　"　　　　 移至当前行上一次所在位置（在光标移动之后）――一个双引号<br/>　　''　　　　移至当前行上第一次所在位置的行的开头处(在光标移动之后)――两个单引号0.<br/>头两个和最后一个就已经挺好用的了<br/><br/>19.<br/>同时vi多个文件时，CTRL-SHIFT-6回到上一个文件，在本次vi的文件和上次vi的文件之间切换。<br/>但是我发现一个BUG：在用CTRL-SHIFT-6切换到上一个文件后，用:args查看多文件vi状态时，<br/>屏幕底部仍然显示目前vi的是刚才的文件。<br/>(在HP-UX,Solaris,AIX上通过)<br/>也可以使用:<br/>:e#<br/>进行切换<br/>ctrl+shift+6=:e#回到上一个文件，哇哈哈，终于找到了，对应的是:next简写为:n到下个文件，用files貌似更能看清当前打开的文件列表<br/><br/>20.<br/>sco 下VI 要在文本前同样的字符加用<br/>%s/^/要加的内容/g 要在文本后同样的字符加<br/>%s/$/要加的内容/g <br/>汗，这样利用查找替换<br/><br/>21.<br/>如何去掉文本中的 ^M 硬回车？不必用binary传回去再ascii传回来的方式，用shell或者unix语句实现。<br/><br/>cat filename &#124;tr -d '&#92;015' >newfile<br/>不同的unix系统还存在一些其他不同的命令,如:doscp <br/>sed 也可以实现这个功能. <br/><br/>dos2unix filename filename2<br/>反之<br/>unix2dos filename filename2 <br/><br/>在vi 中用:$s/^M//g<br/>^是crtl-V crtl-M <br/>我常用的是dos2unix<br/><br/>22.如何在"unix命令行"下将一个文件的某字符串用另一个串换掉<br/><br/>sed 's/string1/string2/gp' file1 > file2<br/><br/><br/>23.将/etc/hosts下所有的地址都ping 2次<br/><br/>1 #/usr/bin/sh<br/>2 #grad /etc/hosts and ping each address<br/>3 cat /etc/hosts&#124;grep -v '^#' &#124; while read LINE<br/>4 do<br/>5 ADDR=`awk '&#123;print $1&#125;'`<br/>6 for MACHINE in $ADDR<br/>7 do<br/>8 ping $MACHINE -n 2<br/>9 done<br/>10 done<br/><br/>24.<br/>到前一个函数[[ ，到下一个函数]] ，括号配对% ，交叉参考Ctrl_] (事先用ctags做索引），回来用e# ` 编辑一个函数：vi -t 函数名 ,编辑加密文本vi -X<br/>%括号匹配我介绍过，:e#回来可以用ctrl+o替代，更优雅<br/><br/>25.<br/>在插入模式下ctrl+p，自动补齐剩余单词，以赖规则：tags，以有的单词等等<br/>还ctrl_n呢<br/><br/> <br/>例一、两个常用的指令序列<br/><br/>xp 左右交换光标处两字符的位置。 <br/>ddp 上下交换光标处两行的位置。 <br/><br/>例二、重复输入同一字符<br/><br/>有时，我们可能想多次输入同一字符，VIM的插入功能可以很好的完成这项工作<br/><br/>命令 80i=^ESC 一次可以输入80个字符= ,当然，80a=^ESC 也可以完成上述功能。<br/><br/>请注意：此处的^ESC表示键盘左上方上的ESC键。<br/><br/>例三、将两个文本数据文件按行逐条合并，并给出标尺<br/><br/>数据文件1内容如下：<br/>1-----<br/>2-----<br/>3-----<br/><br/>数据文件2内容如下：<br/>1=====<br/>2=====<br/>3=====<br/><br/>要求的结果如下：<br/>&#124;--------1---------2---------3---------4---------5<br/>1-----<br/>1=====<br/>&#124;--------1---------2---------3---------4---------5<br/>2-----<br/>2=====<br/>&#124;--------1---------2---------3---------4---------5<br/>3-----<br/>3=====<br/><br/>也许您会说，这还不简单，无非是反复拷贝、粘贴，任何一款文本编辑器都能完成上述功能。可是，如果这两个文件都很大，每个文件都成千上万行，恐怕简单的拷贝、粘贴就难以胜任了。因此，我们所关心的，是找到一种行之有效的方法，把枯燥乏味的工作留给计算机，我们只需发布指令。为达到此目的，请按以下步骤执行：<br/><br/>㈠、将两文件合并，结果如下<br/>1-----<br/>2-----<br/>3-----<br/>1=====<br/>2=====<br/>3=====<br/><br/>㈡、在两文件头尾相接的地方插入标志行，用以区分两个文件，本文采用的是一整行！字符<br/>1-----<br/>2-----<br/>3-----<br/>!!!!!!!!!!!!!!!!!!!!!!!!<br/>1=====<br/>2=====<br/>3=====<br/><br/>㈢、在标志行的下方输入标尺<br/>1-----<br/>2-----<br/>3-----<br/>!!!!!!!!!!!!!!!!!!!!!!!!<br/>&#124;--------1---------2---------3---------4---------5<br/>1=====<br/>2=====<br/>3=====<br/><br/>㈣、执行宏命令脚本merge_2r.vim，即在VIM编辑器中按如下键 :so merge_2r.vim 回车<br/><br/>㈤、按下键盘上的=键，执行的结果如下<br/>&#124;--------1---------2---------3---------4---------5<br/>1-----<br/>1=====<br/>&#124;--------1---------2---------3---------4---------5<br/>2-----<br/>2=====<br/>&#124;--------1---------2---------3---------4---------5<br/>3-----<br/>3=====<br/>&#124;--------1---------2---------3---------4---------5<br/>!!!!!!!!!!!!!!!!!!!!!!!!<br/>&#124;--------1---------2---------3---------4---------5<br/><br/><br/>㈥、将最后三行删除，即可得到我们需要的结果<br/>&#124;--------1---------2---------3---------4---------5<br/>1-----<br/>1=====<br/>&#124;--------1---------2---------3---------4---------5<br/>2-----<br/>2=====<br/>&#124;--------1---------2---------3---------4---------5<br/>3-----<br/>3=====<br/><br/>怎么样，简单吗？请大家自己实际尝试一下。下面，我来详细讲解宏命令脚本merge_2r.vim 。<br/><br/>该脚本内容如下：<br/><br/>"--------------------------------------------------------------------<br/>"Macro Function : Merge File1 And File2,Have Ruler in every record<br/>" Date : 2001/12/01<br/>" Author : Yan Shi<br/>"--------------------------------------------------------------------<br/>"1----- <br/>"2----- &#125; Sample File1<br/>"3-----<br/>"!!!!!!!!!!!!!!!!!!!!!!!! Flag Row<br/>"&#124;--------1---------2---------3---------4---------5 Ruler<br/>"1===== <br/>"2===== &#125; Sample File2<br/>"3===== <br/>"--------------------------------------------------------------------<br/>:1<br/>:map = ma/!!!!!^M+:.co 'a-1^M/!!!!!^M2+:.m'a^M+=<br/><br/>前14行每行都以"开始，表明该行是注释行，实际并不执行，只是方便读者阅读，只有最后两行才是真正的代码行。请注意：本例中的^M表示键盘上的回车键，并非^和M两个字符。为了讲述清楚，我把命令行分解开，逐一说明。<br/><br/>首先将第一行置为当前行，然后执行map命令，将一大串VIM指令映像给字符=。这一大串VIM指令共分9步执行：<br/><br/>ma 将数据文件一的第一行标记为a<br/>1-----<br/>2-----<br/>3-----<br/>!!!!!!!!!!!!!!!!!!!!!!!!<br/>&#124;--------1---------2---------3---------4---------5<br/>1=====<br/>2=====<br/>3=====<br/><br/>/!!!!!^M 找到标志行,置为当前行<br/>1-----<br/>2-----<br/>3-----<br/>!!!!!!!!!!!!!!!!!!!!!!!!<br/>&#124;--------1---------2---------3---------4---------5<br/>1=====<br/>2=====<br/>3=====<br/><br/>+ 光标下移一行,即把标尺行置为当前行<br/>1-----<br/>2-----<br/>3-----<br/>!!!!!!!!!!!!!!!!!!!!!!!!<br/>&#124;--------1---------2---------3---------4---------5<br/>1=====<br/>2=====<br/>3=====<br/><br/>:.co 'a-1^M 把标尺行复制到标记行(数据文件一的第一行)的上方<br/>&#124;--------1---------2---------3---------4---------5<br/>1-----<br/>2-----<br/>3-----<br/>!!!!!!!!!!!!!!!!!!!!!!!!<br/>&#124;--------1---------2---------3---------4---------5<br/>1=====<br/>2=====<br/>3=====<br/><br/>/!!!!!^M 再次找到标志行,置为当前行<br/>&#124;--------1---------2---------3---------4---------5<br/>1-----<br/>2-----<br/>3-----<br/>!!!!!!!!!!!!!!!!!!!!!!!!<br/>&#124;--------1---------2---------3---------4---------5<br/>1=====<br/>2=====<br/>3=====<br/><br/>2+ 光标下移2行，即数据文件二的第一行置为当前行<br/>&#124;--------1---------2---------3---------4---------5<br/>1-----<br/>2-----<br/>3-----<br/>!!!!!!!!!!!!!!!!!!!!!!!!<br/>&#124;--------1---------2---------3---------4---------5<br/>1=====<br/>2=====<br/>3=====<br/><br/>:.m'a^M 把数据文件二的第一行移至标记行的下方<br/>&#124;--------1---------2---------3---------4---------5<br/>1-----<br/>1=====<br/>2-----<br/>3-----<br/>!!!!!!!!!!!!!!!!!!!!!!!!<br/>&#124;--------1---------2---------3---------4---------5<br/>2=====<br/>3=====<br/><br/>+ 光标下移一行，即数据文件一的第二行置为当前行<br/>&#124;--------1---------2---------3---------4---------5<br/>1-----<br/>1=====<br/>2-----<br/>3-----<br/>!!!!!!!!!!!!!!!!!!!!!!!!<br/>&#124;--------1---------2---------3---------4---------5<br/>2=====<br/>3=====<br/><br/>= 这一步很关键，是典型的递归调用，重复完成以上步骤<br/><br/>例四、在文件中置入行号<br/><br/>工作中，我们有时希望把行号置入文件中，而VIM提供的功能 :set nu 只能显示行号，不能编辑或将其置入文件当中，下面的宏命令脚本row_num.vim可以完成此项功能。<br/><br/>"------------------------------------------<br/>"Macro Function : Source File Add Row_Num<br/>" Date : 2001/12/01<br/>" Author : Yan Shi<br/>"------------------------------------------<br/>:%s/^/^I/<br/>:$<br/>:let end=line(".")<br/>:1<br/>"------------------------------------------<br/>:let num=1<br/>:while num<=end<br/>:let line=getline(".")<br/>:let temp=substitute(line,$,num,"")<br/>:call setline(".",temp)<br/>:+<br/>:let num=num+1<br/>:endwhile<br/>"------------------------------------------<br/><br/>请注意：本例中的^I表示键盘上的TAB键，并非^和I两个字符。下面，我针对该宏命令脚本逐一讲解。<br/><br/>:%s/^/^I/ 每一行的行首添加一个TAB字符<br/>:$ 到文件的末行<br/>:let end=line(".") 末行的行号 ==〉变量 END，函数line的功能是取得指定行的行号，此处参数"."表示当前行<br/>:1 到文件的首行<br/>"------------------------------------------<br/>:let num=1 1 ==〉计数器<br/>:while num<=end<br/>:let line=getline(".") 取当前行的内容 ==〉变量 LINE<br/>:let line=substitute(line,$,num,"") 在变量 LINE 的前面置入行号<br/>:call setline(".",line) 将变量 LINE 的内容写回当前行<br/>:+ 下移一行<br/>:let num=num+1 计数器加一<br/>:endwhile 循环执行，直到文件结束<br/>"------------------------------------------<br/>真正的高级技巧，不过貌似太高了，一般用不着……<br/><br/>有关正则表达式的使用<br/><br/>UNIX/LINUX 下的很多工具之所以强大、灵活，关键是因为有了正则文法和元字符，这也是VIM乃至UNIX/LINUX系统的精华所在。正因为使用灵活，因此掌握起来比较吃力，如果不是真正理解，实际运用中会出现千奇百怪的错误。因此，有必要对这部分知识多花些气力。下面结合具体实例讲解。<br/><br/>例五、有一文件，包含某外企的中国员工的资料，首先是姓名，然后是两个空格,其次是15位身份证号码。<br/><br/>zhang.fei 430759701022003<br/>diao.chan 651302801225012<br/>guan.yu 342869680413001<br/>xi.shi 120638780214006<br/>liu.bei 210324650708001<br/><br/>现在，有以下问题需要解决：<br/><br/>按照外国人的习惯，应该是名在前，姓在后。因此，文件中的姓名字段需要修改。 <br/>姓与名的首字母应该大写。 <br/>根据身份证号码，还可以判断出生年月日，将其作为一个新字段添加。 <br/>根据身份证号码，可以判断出性别。若为男性，添加male，若为女性，添加female 。 <br/>将男女员工分开，男员工在前，女员工在后。 <br/>将各字段数据左对齐 <br/><br/>最终结果如下：<br/><br/>Fei.Zhang 430759701022003 1970/10/22 male <br/>Yu.Guan 342869680413001 1968/04/13 male <br/>Bei.Liu 210324650708001 1965/07/08 male <br/>-----------------------------------------------<br/>Chan.Diao 651302801225012 1980/12/25 female<br/>Shi.Xi 120638780214006 1978/02/14 female<br/><br/>为了完成上述功能，只需执行脚本employee.vim ，使用方法为 :so employee.vim 回车即可。<br/><br/>脚本内容如下：<br/><br/>:%s/ / /<br/>:%s/&#92;(............&#92;)&#92;( *&#92;)/&#92;1/<br/>:%s/&#92;([A-Za-z][A-Za-z]*&#92;)&#92;(&#92;.&#92;)&#92;([A-Za-z][A-Za-z]*&#92;)/&#92;u&#92;3&#92;2&#92;u&#92;1/<br/>:%s/$/ xxxxxx/<br/>:%s/&#92;([0-9]&#92;&#123;6&#125;&#92;)&#92;([0-9]&#92;&#123;6&#125;&#92;)&#92;([0-9]&#92;&#123;3&#125;&#92;) &#92;(xxxxxx&#92;)/&#92;1&#92;2&#92;3 &#92;2/<br/>:%s/&#92;(..&#92;)&#92;(..&#92;)&#92;(..&#92;)$/19&#92;1&#92;/&#92;2&#92;/&#92;3<br/>:%s/$/ xxxxxx/<br/>:%s/&#92;([0-9]&#92;&#123;14&#125;[13579]&#92;)&#92;(.*&#92;)&#92;(xxxxxx&#92;)/&#92;1&#92;2male /<br/>:%s/&#92;([0-9]&#92;&#123;14&#125;[02468]&#92;)&#92;(.*&#92;)&#92;(xxxxxx&#92;)/&#92;1&#92;2female/<br/>:$<br/>:s/.*/&^M-----------------------------------------------<br/>:g/female/.m$<br/><br/>在这个脚本中,使用了大量的正则表达式，这里仅对涉及到的正则表达式做一简要介绍。有关正则表达式的内容相当多，本文不可能占用大量篇幅叙述，请大家谅解。<br/><br/>% 地址范围符号，代表文件中的所有行,作用等同于地址范围 1,$<br/>. 与任意单字符(换行符除外)匹配，例如 y.s 可以匹配 yas y.s 或 y s 等等。<br/>* 与前一字符的0次或多次出现匹配，例如 y*s 可以匹配 yys yyyyys 或 s 等等。<br/>$ 与行尾匹配。<br/>& 代表模式匹配中出现的字符串，例如 s/abc/&def 是把当前行的abc替换成abcdef 。<br/>[] 匹配[]中出现的字符，例如[abc]匹配字符 a，b 或 c ，[a-zA-Z]匹配所有的英文字符。<br/>&#92;( &#92;) &#92;(和&#92;)之间出现的内容可以由&#92;num来替代。<br/>&#92;1&#92;2&#92;3 替代&#92;(和&#92;)之间出现的内容。<br/>&#92;u 将后续字符串的首字母大写。<br/>&#92;&#123;num&#125; 与前一字符的num次出现匹配。<br/><br/>现在，我们对脚本逐条讲解，希望能帮助大家理解正则文法。<br/><br/>⑴:%s/ / /<br/>将文件中每行出现的2个空格替换为10个空格。<br/><br/>zhang.fei 430759701022003<br/>diao.chan 651302801225012<br/>guan.yu 342869680413001<br/>xi.shi 120638780214006<br/>liu.bei 210324650708001<br/><br/>⑵:%s/&#92;(............&#92;)&#92;( *&#92;)/&#92;1/<br/>保留行首的12个字符，将其余的空格删除，这样，前两个字段就对齐了。<br/><br/>zhang.fei 430759701022003<br/>diao.chan 651302801225012<br/>guan.yu 342869680413001<br/>xi.shi 120638780214006<br/>liu.bei 210324650708001<br/><br/>⑶:%s/&#92;([A-Za-z][A-Za-z]*&#92;)&#92;(&#92;.&#92;)&#92;([A-Za-z][A-Za-z]*&#92;)/&#92;u&#92;3&#92;2&#92;u&#92;1/<br/>将文件中每行出现的雇员姓名互换，并将首字母大写。<br/><br/>Fei.Zhang 430759701022003<br/>Chan.Diao 651302801225012<br/>Yu.Guan 342869680413001<br/>Shi.Xi 120638780214006<br/>Bei.Liu 210324650708001<br/><br/>⑷:%s/$/ xxxxxx/<br/>在每一行的行尾添加2个空格和6个x<br/><br/>Fei.Zhang 430759701022003 xxxxxx<br/>Chan.Diao 651302801225012 xxxxxx<br/>Yu.Guan 342869680413001 xxxxxx<br/>Shi.Xi 120638780214006 xxxxxx<br/>Bei.Liu 210324650708001 xxxxxx<br/><br/>⑸:%s/&#92;([0-9]&#92;&#123;6&#125;&#92;)&#92;([0-9]&#92;&#123;6&#125;&#92;)&#92;([0-9]&#92;&#123;3&#125;&#92;) &#92;(xxxxxx&#92;)/&#92;1&#92;2&#92;3 &#92;2/<br/>将xxxxxx替换成出生年月日。<br/><br/>Fei.Zhang 430759701022003 701022<br/>Chan.Diao 651302801225012 801225<br/>Yu.Guan 342869680413001 680413<br/>Shi.Xi 120638780214006 780214<br/>Bei.Liu 210324650708001 650708<br/><br/>⑹:%s/&#92;(..&#92;)&#92;(..&#92;)&#92;(..&#92;)$/19&#92;1&#92;/&#92;2&#92;/&#92;3<br/>将年月日用/字符分隔，并在年前添加19。<br/><br/>Fei.Zhang 430759701022003 1970/10/22<br/>Chan.Diao 651302801225012 1980/12/25<br/>Yu.Guan 342869680413001 1968/04/13<br/>Shi.Xi 120638780214006 1978/02/14<br/>Bei.Liu 210324650708001 1965/07/08<br/><br/>⑺:%s/$/ xxxxxx/<br/>在每一行的行尾添加2个空格和6个x<br/><br/>Fei.Zhang 430759701022003 1970/10/22 xxxxxx<br/>Chan.Diao 651302801225012 1980/12/25 xxxxxx<br/>Yu.Guan 342869680413001 1968/04/13 xxxxxx<br/>Shi.Xi 120638780214006 1978/02/14 xxxxxx<br/>Bei.Liu 210324650708001 1965/07/08 xxxxxx<br/><br/>⑻:%s/&#92;([0-9]&#92;&#123;14&#125;[13579]&#92;)&#92;(.*&#92;)&#92;(xxxxxx&#92;)/&#92;1&#92;2male /<br/>身份证号码末位是奇数的，将xxxxxx替换成male <br/><br/>Fei.Zhang 430759701022003 1970/10/22 male <br/>Chan.Diao 651302801225012 1980/12/25 xxxxxx<br/>Yu.Guan 342869680413001 1968/04/13 male <br/>Shi.Xi 120638780214006 1978/02/14 xxxxxx<br/>Bei.Liu 210324650708001 1965/07/08 male <br/><br/>⑼:%s/&#92;([0-9]&#92;&#123;14&#125;[02468]&#92;)&#92;(.*&#92;)&#92;(xxxxxx&#92;)/&#92;1&#92;2female/<br/>身份证号码末位是偶数的，将xxxxxx替换成female<br/><br/>Fei.Zhang 430759701022003 1970/10/22 male <br/>Chan.Diao 651302801225012 1980/12/25 female<br/>Yu.Guan 342869680413001 1968/04/13 male <br/>Shi.Xi 120638780214006 1978/02/14 female<br/>Bei.Liu 210324650708001 1965/07/08 male <br/><br/>⑽:$ 到文件的最后一行<br/><br/>⑾:s/.*/&^M-----------------------------------------------<br/>在文件的最末行插入一行 "-" 字符。<br/><br/>Fei.Zhang 430759701022003 1970/10/22 male <br/>Chan.Diao 651302801225012 1980/12/25 female<br/>Yu.Guan 342869680413001 1968/04/13 male <br/>Shi.Xi 120638780214006 1978/02/14 female<br/>Bei.Liu 210324650708001 1965/07/08 male <br/>-----------------------------------------------<br/><br/>⑿:g/female/.m$<br/>将所有的女员工记录移至文件尾。<br/><br/>Fei.Zhang 430759701022003 1970/10/22 male <br/>Yu.Guan 342869680413001 1968/04/13 male <br/>Bei.Liu 210324650708001 1965/07/08 male <br/>-----------------------------------------------<br/>Chan.Diao 651302801225012 1980/12/25 female<br/>Shi.Xi 120638780214006 1978/02/14 female<br/><br/>笔者目前正在为某外资公司从事大型机（IBM S/390）的软件开发，一切工作都在TSO环境中进行。为了对编写的程序进行测试，必须准备测试数据。有过大型机开发经验的人会知道，通过TSO，输入字符型数据还可以，如果要输入16进制数据，操作起来很麻烦。因为16进制数是纵向排列的，输入时既不方便，又很容易错位。怎么解决呢？我尝试了几种办法，实际证明，用VIM最方便。<br/><br/>例六、下列数据 1234567890ABCDEF ，将其变成 13579ACE 24680BDF 的形式，这样，数据就可以很方便的粘贴到TSO环境中了。<br/><br/>下面给出宏命令脚本change_d.vim<br/><br/>"----------------------------------------------------<br/>"Macro Function : Convert Char Arrange Direction<br/>"<br/>" Sample : 40 50 60 ==> 4 5 6<br/>" 0 0 0<br/>" Date : 2001/12/01<br/>" Author : Yan Shi<br/>"----------------------------------------------------<br/>:s/.*/&^M/<br/>:1<br/>:map = malx+$p-`al=<br/><br/>说明如下:<br/><br/>⑴ :s/.*/&^M/ 在数据行下方添加一空行。<br/>⑵ :1 回到文件的首行的首字符。<br/>⑶ :map = malx+$p-`al= 将一大串VIM命令映像给字符=<br/><br/>① ma 将首字符标记为a<br/>② l 光标右移一个字符<br/>③ x 删除光标处字符<br/>④ + 移至下一行<br/>⑤ $ 到行尾<br/>⑥ p 将删除的字符粘贴<br/>⑦ - 回至上一行<br/>⑧ `a 返回到标记字符处<br/>⑨ l 光标右移一个字符<br/>⑩ = 递归调用,重复以上步骤，直到将该行所有的数据处理完。 
]]>
</description>
</item><item>
<link>http://jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] vi高级命令]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>