Chinaunix首页 | 论坛 | 博客
  • 博客访问: 489604
  • 博文数量: 23
  • 博客积分: 398
  • 博客等级: 一等列兵
  • 技术积分: 850
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-03 22:18
文章分类

全部博文(23)

文章存档

2013年(9)

2012年(14)

分类: Python/Ruby

2012-10-17 08:26:48

文件从windows到linux如何解决中多余的^M


  前些天,我用在linux下使用这个工具格式化我的c/c++代码(因为这些代码从别处copy过来的,有些凌乱,我强烈反对没有良好的编码风格,老想着编完后依赖这个工具),格式化很简单但是当我用vim打开一看发现有很多怪怪的^M符号,让人觉得很不爽,我是一个完美主义者,怎么可以容忍这个瑕疵呢?

    于是在网上倒腾一番后终于知道怎么回事啦,我稍微整理一下分享给大家。
    Windows等操作系统用的文本换行符和UNIX/Linux操作系统用的略有不同,Win系统下输入的换行符在UNIX/Linux下不会显示为“换行”,而是显示为^M(ctrl+v+m组合键)这个符号(占一个字符大小,不是 ^ 和 M 的组合)。Linux下很多文本编辑器(如vim)会在显示这个标记之后,补上一个自己的换行符,以避免内容混乱(只是用于显示,补充的换行符不会写入到文件中)。Win下的回车换行是"\r\n" ,而一些Linux下是"\n",所以,"\r"就多余了。在计算机诞生之初,存储设备十分昂贵。于是有人就提出没有必要用两个字符来表示一行的结束。估计Unix/Linux也是这么考虑的。
    明白了之所以然问题就好解决了。
方法一 :
vim切换到命令模式,然后
  “ : %s/^M$//g ”    
                           %指匹配整个文件
                           s是置换的意思
                          ^M要用ctrl+v+m 组合键敲入
                           $表示匹配行尾的内容
                           g表示每行中匹配到的内容都要置换

举个例子:如果要把文件中的x都替换成y就可以这样匹配
   :%s/x/y/g 

我们要替换换行符为空,所以得这样输入:

   “%s/^M//g”      (这里的^M仍是ctrl+v+m  
   或 “%s/\r//g

方法二 :
   其实,这不能算另一个方法,因为这只是indent格式化+vim替换这两个功能的结合,可以做到一劳永逸,比较方便而已。
   最近我看了一点点shell脚本基础,于是我就想到不妨写一个脚本代替繁琐的命令输入。生活还是很公平的:只有先苦才会有后甜,你说是不是?
  看似简单,可是问题来了(对于我这样的菜鸟,很正常!)。前面的用indent格式化代码部分比较好弄,可是后面问题来了,虽然经常用vim可是在shell脚本里我该怎么执行vim的末行命令“%s/^M//g”呢。功夫不负有心人,我在vim --help下查到以下参数:
   -e                Ex 模式 (同 "ex")
   -s                安静(批处理)模式 (只能与 "ex" 一起使用)
   -c         加载第一个文件后执行

于是我在脚本里这样写:
vim  -e  -s  -c  "%s/\r//g"   $file_path

运行脚本后问题又来了,这样貌似可以替换成功,但是vim等待我继续键入命令,我得输入wq或x回车才能保存退出。都说了我是完美主义者,是不能容忍这点瑕疵的。估计在网上搜也不好搜,so我很庆幸有邮件列表的帮助,里面的大神总是很热心回答各种疑问的。最后在各种帮助下完成了,vim  -e  -s  -c  "%s/\r//g"  -c "wq"  $file_path
还找到了另外一个方法(请看脚本注释)脚本如下:

点击(此处)折叠或打开

  1. # 文件名:indentEX.sh
  2. #!/bin/sh
  3. PARAM="-linux -brnce -cdw" #我喜欢的代码风格

  4. # 参照GNU,Kernighan & Ritchie,Berkeley风格,可以制定了自己风格
  5. #PARAM="-bad -bap -bbb -bbo -nbc -bl -bli0 -bls -c33 -cd33 -ncdb -ncdw -nce -cli0 -cp33 -cs -d0 -nbfda -di2 -nfc1 -nfca -hnl -ip5 -l75 -lp -pcs -nprs -psl -saf -sai -saw -nsc -nsob -nss -i4 -ts4 -ut"

  6. # 用indent格式化代码
  7. indent $PARAM "$@" # $@==$*表示全部参数
  8. if [ $? != 0 ]
  9. then
  10.    exit 1
  11. fi

  12. if [ $# -ge 3 ] #检查参数个数,是否有-o
  13. then
  14.    file_path=$3
  15. else
  16.    file_path=$1
  17. fi

  1. vim -e -s -c "%s/\r//g" -c "wq" $file_path 
  2. # 或者用sed
  3. #sed -i 's/\^M//g' $file_path   # 这里的^M是ctrl+v+m,或者用\r
  4. echo "ok"
在你c代码目录下放置一个这样的shell脚本,只要执行$sh indentEX.sh filename.c 就可以很轻松完成格式化了,你说是不是便捷多了?
    另外只要不嫌麻烦你也可以自己动手写一个小程序(c/c++)替换^M,只要在shell脚本里调用一下就ok了。

 注:本博客的文章除注明有“转载”字样的外,均为原创,欢迎转载,请注明文字出处,谢谢!
阅读(8990) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~