一、问题产生的原因:

DOS/Windows和Linux/Unix的文件换行回车格式不同,基于 DOS/Windows 的文本文件在每一行末尾有一个 CR(回车)和 LF(换行),而 UNIX 文本只有一个换行。
对于换行这个动作,unix下一般只有一个0x0A表示换行(“\n”),windows下一般都是0x0D和0x0A两个字符(“\r\n”),苹果机(MAC OS系统)则采用回车符CR表示下一行(\r)
Unix系统里,每行结尾只有 “<换行>”,即 “\n”;
Windows系统里面,每行结尾是 “<回车><换行>”,即”\r\n”;
Mac系统里,每行结尾是”<回车>”,即”\r”。
一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;而Windows里的文件在Unix下打开的话,在每行的结尾会多一个^M字符。即 “\r” = ^M
Dos和windows采用回车+换行 CR+LF(\r\n)表示下一行,即^M$($不是换行符的表示,换行符没有表示出来,$是文本结束EOF的表示);
UNIX/Linux采用换行符LF表示下一行,即\n;LF使用’\n’符号表示, ASCII代码是10, 十六制为0x0A.
MAC 系统则采用回车符CR表示下一行,即\r;CR用符号’\r’表示, 十进制ASCII代码是13, 十六进制代码为0x0D;

所以Windows平台上换行在文本文件中是使用 0d 0a 两个字节表示, 而UNIX和苹果平台上换行则是使用0a或0d一个字节表示.由于dos风格的换行使用\r\n,把这样的文件上传到unix,有些版本的vi不能识别\r,所以vi显示时在行尾会出现^M出来,但是有些就能识别\r\n,正常显示回车换行。

二、用sed进行转换

以下 sed 调用将把 DOS/Windows 格式的文本———->>可信赖的 UNIX 格式:
sed -i 's/^M$//g' 即寻找以 ^M 结尾的行,string^M\n——》string\n.
sed -i 's/\r$//g' #这个命令也可以。

反过来,也可以把UNIX——>DOS. \n——->\r\n.
sed -i 's/$/\r\n/' #在该脚本中,’$’ 规则表达式将与行的末尾匹配,而 ‘\r’ 告诉 sed 在其之前插入一个回车。在换行之前插入回车,立即,每一行就以 CR/LF 结束。

1. vim中查询修改文件编码格式

:set ff 查看当前文本的模式类型,一般为dos,unix
:set ff=dos 设置为dos模式, 也可以用 sed -i ‘s/$/\r/‘
:set ff=unix 设置为unix模式,也可以用一下方式转换为unix模式:sed -i ‘s/.$//g’
:set fileencoding查看现在文本的编码
:set fenc=编码 转换当前文本的编码为指定的编码
:set enc=编码 以指定的编码显示文本,但不保存到文件中。这里的“编码”常见为gbk utf-8 big5 cp936

2. 在Linux/Window下批量处理文件格式

2.1 使用 sed + grep

sed -i “s/原字符串/新字符串/g” grep 原字符串 -rl 所在目录
eg: sed -i ‘s/$/\r/g’ grep '$' -rl . #批量转unix to dos (亲测可用)

2.2 使用find + sed

eg: find . -name “*.sh” | xargs sed -i ‘s/\r$//g’ #批量转dos to unix (亲测可用!)

2.3 在git 下,对已经编辑过的文件进行转换。

git status |grep “.tcl”|sed “s/modified: //“|xargs sed -i “s/\r$//g”

其他方法:

在Vim显示^M字符的原因:在Windows下换行使用CRLF两个字符来表示,其中CR为回车(ASCII=0x0D),LF为换行(ASCII=0x0A),而在Linux下使用LF一个字符来表示。在Linux下使用vi来查看一些Windows下创建的文本文件时,有时会发现在每一行尾部有^M字符,其实它是显示CR回车字符。
sublime 设置为:windows使用的CRLF,unix使用的是 LF。按你的情况,应该在Setting-User中设置”default_line_ending”:”unix”就可以解决这个问题。
下面有一些方法可以处理这种问题(其实这只是Windows和Linux平台表示回车的方法不一样而已!!!!)。

2.1 使用dos2unix

一般Linux发行版中都带有这个小工具,只能把DOS转换为UNIX文件,命令如下:
# dos2unix dosfile.txt 命令会去掉行尾的^M符号。

2.2 使用tr

使用tr命令拷贝标准输入到标准输出,替换或者删除掉选择的字符,只能把DOS转换为UNIX文件,命令如下:
# tr -d ‘\r’< dosfile.txt > unixfile.txt

2.3 使用vim

Vim是一个vi的改进版本,可以运行在Windows和Linux平台上,使用方法如下:
DOS转UNIX::setfileformat=unix
UNIX转DOS::setfileformat=dos
你也可以使用ff来替代fileformat
注:为了能让vim可以自动识别DOS和UNIX文本文件格式,可以在.vimrc(Linux)或_vimrc(Windows)配置文件中加入如下一行设置:
setfileformats=dos,unix
设置完成后,使用vim打开DOS文本文件就不会显示^M字符了。

2.4 使用sed

  1. DOS文件格式中使用CR/LF换行,在Unix下仅使用LF换行,sed替换命令如下:<br /> DOSUNIX$ sed 's/.$//' dosfile.txt > unixfile.txt<br /> UNIXDOS$ sed 's/$/\r/' unixfile.txt > dosfile.txt

2.5 使用Perl

  1. Perl是相当直接,你添加或删除掉文件每行结尾的CR字符。<br /> DOSUNIXperl -p -e 's/\r$//' <dosfile.txt> unixfile.txt<br /> UNIXDOSperl -p -e 's/$/\r/' <unixfile.txt> dosfile.txt

总结

  1. 还有其它DOSUNIX文本文件的转换方法,我个人推荐使用vim命令。但是,对于大型的文件,推荐使用perl工具,你也不希望在vimEmacs中打开几个G的文本文件。