LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 8494|回复: 23

变态vi问答

[复制链接]
发表于 2004-3-1 15:34:38 | 显示全部楼层 |阅读模式
有个文本文件内容如下:
new
newabc
news
newspaper
new new newspaper
new newsabc

BT问:如何把所有的new读换成old?
小猪答:简单: % s/new/old/g
结果如下:
old
oldabc
olds
oldspaper
old old oldspaper
old oldsabc

BT:我要只有单词new变成old,其它所有甚么news,newxxx中的new不变
小猪挠了挠头:嗯... 这样,用精确匹配: % s/\<new\>/old/g
结果如下:
old
newabc
news
newspaper
old old newspaper
old newsabc

BT:现在我要单词new不变,其它所有甚么news, newxxx中的new都变成old
小猪又挠了挠头:嗯...  % s/new\([^ ]\{1\}\)/old\1/g,结果如下:
new
oldabc
olds
oldspaper
new new oldspaper
new oldsabc

BT:现在文件内容增加了,加上 abcnews, abcnew, xxxnewyyy,
new
newabc
news
newspaper
new new newspaper
new newsabc
abcnews abcnew abcnewspaper
要求所有单词new都不变,其它诸如xxxnew, xxxnewyyy之类的含有new的单词中的new变成old.
小猪:晕.......

哪位大虾救救猪头?
发表于 2004-3-1 16:29:13 | 显示全部楼层
  1. cat file|sed -e 's/new/old/g' -e 's/\<old\>/new/g'
复制代码
 楼主| 发表于 2004-3-1 16:42:12 | 显示全部楼层
最初由 javalee 发表
  1. cat file|sed -e 's/new/old/g' -e 's/\<old\>/new/g'
复制代码

多谢,不过这个方法小猪是知道的,在vi底下也可以通过两次substitute实现,不过觉得不是很美,我想知道有没有只用一次匹配就完成替换的办法。
另外,这个方法的一个问题是万一原文中有old这个词但又不许被改掉就糟糕了
发表于 2004-3-1 16:57:09 | 显示全部楼层
是够BT的~~~ :p
 楼主| 发表于 2004-3-1 17:23:52 | 显示全部楼层
乍一开始,我企图用% s/\([^ ]\{1\}\)new\([^ ]\{1\}\)/\1old\2/g来做,但是仔细一想,这个式子只能匹配xxxnewyyy这种模式,对于newxx和xxxnew这样的无效,所以不得以再匹配替换两次,太麻烦了,有没有甚么好的匹配方法将xxxnewyyy, xxxnew, newxxx这三种情况一网打尽,并且保留前/后的字符串,只将里面的new摘出来换掉。
偷偷地告诉javalee,这是两年前有个变态公司面试时候问小猪的,今天忽然向起来就向大伙儿请教了。
发表于 2004-3-1 18:07:32 | 显示全部楼层
最初由 littlepig 发表
乍一开始,我企图用% s/\([^ ]\{1\}\)new\([^ ]\{1\}\)/\1old\2/g来做,但是仔细一想,这个式子只能匹配xxxnewyyy这种模式,对于newxx和xxxnew这样的无效,所以不得以再匹配替换两次,太麻烦了,有没有甚么好的匹配方法将xxxnewyyy, xxxnew, newxxx这三种情况一网打尽,并且保留前/后的字符串,只将里面的new摘出来换掉。
偷偷地告诉javalee,这是两年前有个变态公司面试时候问小猪的,今天忽然向起来就向大伙儿请教了。

呵呵~~,我也卡在这里啦~~ ,
发表于 2004-3-1 23:12:28 | 显示全部楼层
用vim可以这样:

  1. new
  2. oldabc
  3. olds
  4. oldspaper
  5. new new oldspaper
  6. new oldsabc
  7. abcolds abcold abcoldspaper
  8. ~
  9. ~
  10. : % s/\([^ ]\{1\}\)new\|new\([^ ]\{1\}\)/\1old\2/g
复制代码
发表于 2004-3-1 23:34:34 | 显示全部楼层
最初由 seablue 发表
用vim可以这样:
  1. new
  2. oldabc
  3. olds
  4. oldspaper
  5. new new oldspaper
  6. new oldsabc
  7. abcolds abcold abcoldspaper
  8. ~
  9. ~
  10. : % s/\([^ ]\{1\}\)new\|new\([^ ]\{1\}\)/\1old\2/g
复制代码
  1. sed 's/\([^ ]\{1\}\)new[color=red]\|[/color]new\([^ ]\{1\}\)/\1old\2/g'
复制代码
原来卡在这里! 谢谢seablue兄!:thank
 楼主| 发表于 2004-3-2 11:39:28 | 显示全部楼层
妙!
嗯,多年来的疙瘩终于解开了,多谢论坛中热心的哥们。
发表于 2004-3-2 19:32:21 | 显示全部楼层
perl, sed, grep, awk, vim 都支持 |
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表