如何以编程方式(不使用vi)将DOS/Windows换行符转换为Unix换行符?

dos2unix和unix2dos命令在某些系统上不可用。 如何使用sed、awk和tr等命令模拟它们?


当前回答

我试着

sed 's/^M$//' file.txt

在OS X以及其他一些方法(修复Dos行结束或http://hintsforums.macworld.com/archive/index.php/t-125.html)。没有一个工作,文件保持不变(顺便说一下,需要按Ctrl + V, Enter来重新生成^M)。最后我使用了TextWrangler。它不是严格意义上的命令行,但它可以工作,而且不会抱怨。

其他回答

你可以使用tr从DOS转换到Unix;但是,只有当CR仅作为CRLF字节对的第一个字节出现在文件中时,才能安全地执行此操作。通常情况都是这样。然后使用:

tr -d '\015' <DOS-file >UNIX-file

注意DOS-file的名称不同于UNIX-file的名称;如果您尝试使用相同的名称两次,您将在文件中没有数据。

你不能反过来做(用标准的'tr')。

如果你知道如何在脚本中输入回车(control-V, control-M输入control-M),那么:

sed 's/^M$//'     # DOS to Unix
sed 's/$/^M/'     # Unix to DOS

其中'^M'是control-M字符。你也可以使用bash ANSI-C引用机制来指定回车:

sed $'s/\r$//'     # DOS to Unix
sed $'s/$/\r/'     # Unix to DOS

但是,如果您必须经常这样做(粗略地说,不止一次),那么安装转换程序(例如dos2unix和unix2dos,或者dou和utod)并使用它们会更明智。

如果你需要处理整个目录和子目录,你可以使用zip:

zip -r -ll zipfile.zip somedir/
unzip zipfile.zip

这将创建一个zip存档,其中行结束符从CRLF更改为cr。unzip将然后将转换后的文件放回原位(并逐个文件询问您-您可以回答:yes to all)。感谢@vmsnomad指出这一点。

这对我很有效

tr "\r" "\n" < sampledata.csv > sampledata2.csv 

在Linux上,使用sed很容易将^M (Ctrl + M)转换为*nix换行符(^J)。

在CLI中就像这样,文本中会有一个换行符。然而,\将^J传递给sed:

sed 's/^M/\
/g' < ffmpeg.log > new.log

你可以使用^V (Ctrl + V), ^M (Ctrl + M)和\(反斜杠)当你输入:

sed 's/^V^M/\^V^J/g' < ffmpeg.log > new.log

作为Jonathan Leffler的Unix to DOS解决方案的扩展,当你不确定文件当前的行结束符时,可以安全地转换为DOS:

sed '/^M$/! s/$/^M/'

这将在转换为CRLF之前检查该行是否已经在CRLF中结束。

蒂姆托维迪!

perl -pe 's/\r\n/\n/; s/([^\n])\z/$1\n/ if eof' PCfile.txt

根据戈登·戴维森的回答。

人们必须考虑到……的可能性。