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

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


当前回答

你可以通过option -c {command}以编程方式使用Vim:

DOS到Unix:

vim file.txt -c "set ff=unix" -c ":wq"

Unix到DOS:

vim file.txt -c "set ff=dos" -c ":wq"

“set ff=unix/dos”表示将文件的fileformat (ff)更改为unix/dos的行尾格式。

":wq"表示将文件写入磁盘并退出编辑器(允许在循环中使用该命令)。

其他回答

使用AWK你可以做到:

awk '{ sub("\r$", ""); print }' dos.txt > unix.txt

使用Perl你可以做到:

perl -pe 's/\r$//' < dos.txt > unix.txt

一个更简单的没有程序的AWK解决方案:

awk -v ORS='\r\n' '1' unix.txt > dos.txt

从技术上讲,“1”是您的程序,因为AWK在给定选项时需要一个。

或者,内部解决方案是:

while IFS= read -r line;
do printf '%s\n' "${line%$'\r'}";
done < dos.txt > unix.txt

你可以使用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指出这一点。

对于Mac OS X,如果您安装了Homebrew (http://brew.sh/):)

brew install dos2unix

for csv in *.csv; do dos2unix -c mac ${csv}; done;

确保您已经复制了文件,因为这个命令将在适当的位置修改文件。 -c mac选项使开关与OS X兼容。

这是超级duper容易与PCRE;

作为脚本,或者用文件替换$@。

#!/usr/bin/env bash
perl -pi -e 's/\r\n/\n/g' -- $@

这将覆盖您的文件! 我建议只在备份时这样做(版本控制或其他方式)