Chinaunix首页 | 论坛 | 博客
  • 博客访问: 305660
  • 博文数量: 54
  • 博客积分: 3050
  • 博客等级: 中校
  • 技术积分: 601
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-25 16:53
文章分类
文章存档

2012年(1)

2011年(7)

2010年(46)

我的朋友

分类: LINUX

2010-01-26 11:18:33

现象:

按照《Unix shell 范例精解》试 sed 例子,用的是书自带光盘里的文件 datafile。但是运行命令(以两个数字结尾的行,将结尾两个数字 ab 替换为 ab.5 )

> sed 's/[0-9][0-9]$/&.5/' datafile

却没有输出,其中某一行最后数字是34,把上面 [0-9][0-9]$ 直接换成 34$ 依旧没有输出。 让人一度以为在这个 Ubuntu 上 $ 元字符不能用。但是这是绝对不可能的,这年头那个敢不支持 POSIX的正则表达式。

继续尝试这个 $元字符,运行例子命令如下(结尾添加 **VACA**):

> sed '/west/,/east/s/$/**VACA**/' datafile

输出如下:

**VACA**t NW Charles Main 3.0 .98 3 34
**VACA**    WE Sharon Gray 5.3 .97 5 23
**VACA**t SW Lewis Dalsass 2.7 .8 2 18
**VACA** SO Suan Chin 5.1 .95 4 15
**VACA**t SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13

觉得 **VACA**t 后的那个 t 很可疑,难道是输出时的覆盖?因为没有替换这个地方阿,再试试

> sed '/west/,/east/s/$/**VA**/' datafile

输出如强烈地支持俺地怀疑,如下:

**VA**est NW Charles Main 3.0 .98 3 34
**VA**n WE Sharon Gray 5.3 .97 5 23
**VA**est SW Lewis Dalsass 2.7 .8 2 18
**VA**rn SO Suan Chin 5.1 .95 4 15
**VA**ast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13

于是来个重定向:

>sed '/west/,/east/s/$/**VA**/' datafile > file
> vim file

显示每行尾部都多了一个 ^M,于是手动删除几个 ^M,使呈以下样子:

northwest       NW  Charles Main        3.0 .98 3   34**VA**      // 手动删除 ^M 以验证
western          WE  Sharon Gray     5.3 .97 5   23**VA**            // 同上
southwest      SW  Lewis Dalsass       2.7 .8  2   18**VA**      // 同上
southern        SO  Suan Chin       5.1 .95 4   15^M**VA**                    // 保留 ^M 以对比
southeast       SE  Patricia Hemenway   4.0 .7  4   17^M**VA**         // 同上
eastern          EA  TB Savage       4.4 .84 5   20^M
northeast       NE  AM Main Jr.     5.1 .94 3   13^M
north             NO  Margot Weber        4.5 .89 5    9^M
central           CT  Ann Stephens        5.7 .94 5   13^M

保存推出后  cat file1, 屏幕显示如下:

northwest NW Charles Main 3.0 .98 3 34**VA**
western WE Sharon Gray 5.3 .97 5 23**VA**
southwest SW Lewis Dalsass 2.7 .8 2 18**VA**
**VA**rn SO Suan Chin 5.1 .95 4 15
**VA**ast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13

证明猜测正确,只是这个 ^M 是什么东西呢?

原因和解决方法:

Google 之,得说法如下:

Linux编辑器vim中删除行尾的^M

有时候,在 Linux 中使用打开曾在 Windows 中编辑过的文件时,会在行尾看到 ^M 字符。看起来总是感觉很别扭。
删除方法如下:
在 Vim 的命令模式中输入 :%s/^M$//g 后,回车即会自动删除该文件中的所有 ^M 字符。
注意: ^M 要用 Ctrl + v,  Ctrl + m 来输入,
 用键盘直接敲^和M是不行的! 后面的 $ 代表匹配行尾的内容,最后的 g 则表示每行中匹配到的内容都要置换--全局替换,否则只替换每行中匹配到的第一个。

又脚本删除方法:
cat file | col -b > file.1  // 这个可以去掉,但是生成文件里汉字变乱码(后一句据说)
sed -e 's/.$//g'  file       // 正确
sed ‘s/^M//' file           // 正确,但是 ^M = Ctrl + v, Ctrl + m

诡异的是,这个 ^M 在文件第一次被修改之后才可见,之前同是用 vim 编辑打开,^M 不可见。

附录:^M 另一个会出现的情况是文件在 windows 和 Linux 系统间通过 Ftp 传送。这是建议方法是:强行设定 ftp 方式为 ascii 方式就可以了啊! 当然也可以通过软件 dos2unix 搞定。// 我没尝试过哈。

从现象到原因到解决方法如下。备份防遗忘。

Tue,Jan/26/2010

阅读(4657) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~