Linux学习笔记:vi,sed,Bash中的文本替换

非常实用,转载!
平时工作的时候写不同部分的代码所要遵循的code rule也是不同的,一共有三套code rule,从命名规则,缩进到宏定义限制都相差不少。我有的时候会弄混,发现使用vi和sed可以很快地处理这类问题,把这几天所用过的命令总结了一下,以后也有个参考。
vi用来处理单个文件很合适,并且可以随时undo;sed适合处理多个文件,如果使用了-i选项处理之前最好做备份
本文中提到的命令均以”"括起来,实际使用中是不需要输入”"的。本文中提到的命令都经过测试,但也许还存在问题,可以e-mai我。
使用vi打开一个文本文件时,如果不是以UNIX LF方式结尾,而是以DOS的 CR/LF结尾,会在屏幕的最后以行提示[DOS]字样。使用winCVS的默认设置所抓的code是以CR/LF结尾的,如果是Bash脚本,直接执行的话会报error。
在vi中执行命令前记得使用ESC切换到一般模式。
在vi中使用”:%! col -bx”可以去掉CR,或者”:%s/^M$//g”。”^M“是回车,vi中输入这种特殊字符需要先ctrl+v,然后按下相应的键,这里是回车键。末尾的g表示替换所有的,否则只替换一次。
vi基本的字符串替换如下:
“:%s/oldstring/newstring/g” 这个是在全文替换oldstring为newstring,如
“:%s/^ *//g” 这条命令去掉所有的行首空格
“:%s/\t/ /g” 这条命令把所有的TAB键换成4个空格
也可以指定行(%表示全文),如
“:123,456 s/old/new/g” 表示把123到456之间的old替换成new,注意s前有个空格,如果没加这个空格,vi将只显示匹配的结果,但不做替换。(奇怪的是”:123,456y”命令不需要加空格)
“:,$ s/old/new/g” 表示在当前行到结尾行之间替换
“:1, s/old/new/g” 表示从开头当当前行。
“:g/match/s/old/new/g” 表示在每个包含match的行中使用new替换old
vi中在编辑模式下输入”:”,可以使用上下方向键来选择历史命令
也可以在命令中使用正则表达式,比如
“:%s/a[b|c|d]e/afe/g” 将把匹配”a[b|c|d]e”的字符串如”abe”"ace”“ade”替换成afe
正则表达式就不详述了,以后有时间再总结吧。
对于多个命令,可以放到一个文件中,如:
vi a.c b.c c.c -s viscript
viscript可以这样写:
:%s/\t/ /g
:w
:next
:%s/\t/ /g
:w
:next
:%s/\t/ /g
:wq
这很显然不是明智的做法,这里只是举个例子。还是用sed处理多个文件吧。

sed单行命令可以和find, xargs结合起来,完成对多个文件的文本替换。如
find . -name “*.[ch]” -exec sed -i ’s/\t/ /g’ {} \;
或者 find . -name “*.[c|h]” | xargs sed -i ’s/\t/ /g’
都可以把当前目录下的.c .h文件中的TAB替换成4个空格。
sed提供的域提取功能可以进行比较复杂的替换如
“sed ’s/\(\/\/*\)\(.*\)/\/\*\2\*\//‘ test.c”
将把test.c中所有的如”//comment” “int a; //comment” “//////////////////”替换成”/*comment*/” “int a; /*comment*/” “/**/”(因为严格ASCII C 只允许这种格式的注释)
这个命令看起来比较乱,如果去掉转义符号”\”就好多了:’s/(\\*)(.*)//*\2*//’,它表示把输入的行中包含”//”分成两个域,第一个域包含”//”或者更多的”/”,第二个域包含”//”之后的字符串,而对“//”之前的字符串不做处理,替换后变成/*加上第二个域\2加上*/。但是请注意,如果”//”注释的结尾处有”\“连接符,或者test.c是以DOS 的CR/LF方式结尾,那么使用这个命令将得不到预期的效果。
“/**/”变回”//”要难一点,我还没想出来怎么用单行的sed命令处理。
关于单行sed命令,可以到这里找到更多的例子(是中文的哦:):http://sed.sourceforge.net/sed1line_zh-CN.html
最后,来总结下Bash历史命令中的字符替换。
关于Bash里’!'的用法,还是在考LPI时记下的,是最简单的历史命令。如
“!armcc”
将执行历史命令中最近一次以armcc开始的命令。
“!n”执行历史命令中为n的命令(可以使用”fc -l”列出最近的10个,可以使用”history“列出更多历史命令)
“!?string ” 执行最近一次包含string的命令。
“!!:s/old/new”替换最后一个命令中的old为new,然后执行
“!72 :gs/old/new” 替换历史命令72中所有的old为new
“^old^new”与”!!:s/old/new”相同。
一般人似乎更喜欢使用上下左右键编辑历史命令,但在编译工程时,选项太多,一条命令有几百个字符,还是使用历史命令字符替换的比较好(不怕麻烦的话也可以先把命令写在文件里然后用vi编辑)
from: http://yolan.bokee.com/6549312.html
标签:
上一篇: recovery ubuntu in winxp || 下一篇:
Linux, News

相关日志

If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.

Leave Comment

(必填)

(必填)