如何以编程方式(不使用vi)将DOS/Windows换行符转换为Unix换行符?
dos2unix和unix2dos命令在某些系统上不可用。 如何使用sed、awk和tr等命令模拟它们?
如何以编程方式(不使用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"表示将文件写入磁盘并退出编辑器(允许在循环中使用该命令)。
其他回答
作为Jonathan Leffler的Unix to DOS解决方案的扩展,当你不确定文件当前的行结束符时,可以安全地转换为DOS:
sed '/^M$/! s/$/^M/'
这将在转换为CRLF之前检查该行是否已经在CRLF中结束。
有趣的是,在Windows上的Git Bash中,sed ""已经做到了:
$ echo -e "abc\r" >tst.txt
$ file tst.txt
tst.txt: ASCII text, with CRLF line terminators
$ sed -i "" tst.txt
$ file tst.txt
tst.txt: ASCII text
我的猜测是,sed在从输入读取行时忽略它们,并且总是将Unix行结束符写入输出。
The solutions posted so far only deal with part of the problem, converting DOS/Windows' CRLF into Unix's LF; the part they're missing is that DOS use CRLF as a line separator, while Unix uses LF as a line terminator. The difference is that a DOS file (usually) won't have anything after the last line in the file, while Unix will. To do the conversion properly, you need to add that final LF (unless the file is zero-length, i.e. has no lines in it at all). My favorite incantation for this (with a little added logic to handle Mac-style CR-separated files, and not molest files that're already in unix format) is a bit of perl:
perl -pe 'if ( s/\r\n?/\n/g ) { $f=1 }; if ( $f || ! $m ) { s/([^\n])\z/$1\n/ }; $m=1' PCfile.txt
注意,这将把文件的统一版本发送到标准输出。如果你想用一个统一的版本替换这个文件,添加perl的-i标志。
我试着
sed 's/^M$//' file.txt
在OS X以及其他一些方法(修复Dos行结束或http://hintsforums.macworld.com/archive/index.php/t-125.html)。没有一个工作,文件保持不变(顺便说一下,需要按Ctrl + V, Enter来重新生成^M)。最后我使用了TextWrangler。它不是严格意义上的命令行,但它可以工作,而且不会抱怨。
你可以通过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"表示将文件写入磁盘并退出编辑器(允许在循环中使用该命令)。